如何选择线之间的两个标记模式,可能发生多次 awk/sed

使用 awksed,我如何能选择线发生在两个不同的标记模式?可能有多个部分用这些模式标记。

例如: 假设文件包含:

abc
def1
ghi1
jkl1
mno
abc
def2
ghi2
jkl2
mno
pqr
stu

起始模式为 abc,结束模式为 mno 所以,我需要输出如下:

def1
ghi1
jkl1
def2
ghi2
jkl2

我使用 sed 匹配一次模式:

sed -e '1,/abc/d' -e '/mno/,$d' <FILE>

有没有办法在 sedawk重复这样做,直到文件结束?

179938 次浏览

必要时使用带有标志的 awk触发打印:

$ awk '/abc/{flag=1;next}/mno/{flag=0}flag' file
def1
ghi1
jkl1
def2
ghi2
jkl2

这是怎么回事?

  • /abc/匹配具有此文本的行,/mno/也是如此。
  • 当找到文本 abc时,/abc/{flag=1;next}设置 flag,然后跳过这一行。
  • 当找到文本 mno时,/mno/{flag=0}取消 flag
  • 最后一个 flag是一个带有默认操作的模式,该操作对应于 print $0: 如果 flag等于1,则打印该行。

有关更详细的描述和示例,以及显示或不显示模式的情况,请参见 如何选择两个图案之间的线条?

这种方法对我很有效:

文件 awk:

BEGIN {
record=0
}


/^abc$/ {
record=1
}


/^mno$/ {
record=0;
print "s="s;
s=""
}


!/^abc|mno$/ {
if (record==1) {
s = s"\n"$0
}
}

使用: awk -f file.awk data..。

编辑: O _ o fedorqui 解决方案比我的好/漂亮多了。

使用 sed:

sed -n -e '/^abc$/,/^mno$/{ /^abc$/d; /^mno$/d; p; }'

-n选项意味着默认情况下不打印。

该模式查找仅包含 abc到仅包含 mno的行,然后执行 { ... }中的操作。第一个操作删除 abc行; 第二个操作删除 mno行; p打印剩余的行。您可以根据需要放松正则表达式。abc范围以外的所有线路。.mno只是不打印。

perl -lne 'print if((/abc/../mno/) && !(/abc/||/mno/))' your_file

这可能对您有用(GNU sed) :

sed '/^abc$/,/^mno$/{//!b};d' file

除了从 abc开始的行和从 mno开始的行之间的行之外,删除所有行

sed '/^abc$/,/^mno$/!d;//d' file

高尔夫球比 Ppotong’s {//!b};d好两个字

空斜杠 //的意思是: “重用最后使用的正则表达式”。这个命令和更容易理解的命令一样:

sed '/^abc$/,/^mno$/!d;/^abc$/d;/^mno$/d' file

返回文章页面 好像是 POSIX:

如果 RE 为空(即没有指定模式) ,sed 的行为就好像指定了最后一个命令中使用的 RE (作为地址或替代命令的一部分)。

来自 只显示两个匹配模式之间的文本的 Don _ Crissti 的回答?

firstmatch="abc"
secondmatch="cdf"
sed "/$firstmatch/,/$secondmatch/!d;//d" infile

这是比 AWK 的应用程序更有效的,见 给你

在之前的响应链接中,帮助我在 Solaris 上运行 ksh的链接是:

sed '1,/firstmatch/d;/secondmatch/,$d'
  • 从第1行到第一次找到 firstmatch,删除。
  • /secondmatch/,$d: 从 secondmatch第一次出现到文件结束,删除。
  • 分号将这两个命令分隔开,这两个命令按顺序执行。

我尝试使用 awk打印两个模式之间的线,而 Pattern n2也匹配 pattern n1。图案1线也应该打印出来。

例如:。 来源

package AAA
aaa
bbb
ccc
package BBB
ddd
eee
package CCC
fff
ggg
hhh
iii
package DDD
jjj

应该有一个输出

package BBB
ddd
eee

其中 pattern n1是 package BBB,pattern n2是 package \w*。请注意,CCC不是一个已知值,因此不能进行字面匹配。

在这种情况下,@sci 的 awk '/abc/{a=1}/mno/{print;a=0}a' file和@fedorqui 的 awk '/abc/{a=1} a; /mno/{a=0}' file都不适合我。

最后,我用 awk '/package BBB/{flag=1;print;next}/package \w*/{flag=0}flag' file解出来了,哈哈

awk '/package BBB/{flag=1;print;next}flag;/package \w*/{flag=0}' file中再多花一点功夫,就可以打印模式2行,也就是说,

package BBB
ddd
eee
package CCC

这也可以通过对标志执行逻辑操作和递增/递减操作来完成:

awk '/mno/&&--f||f||/abc/&&f++' file