如何在awk / sed中多次出现两个标记模式之间select行

使用awksed我怎样才能select两个不同的标记模式之间发生的线? 可能有多个部分标有这些模式。

例如:假设文件包含:

 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有什么方法可以重复执行,直到文件结束?

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

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

这个怎么用?

  • /abc/匹配具有此文本的行,以及/mno/ does。
  • /abc/{flag=1;next}在find文本abc时设置flag 。 然后,它跳过线。
  • /mno/{flag=0}在find文本mnomno设置flag
  • 最后一个flag是一个带有默认行为的模式,即print $0 :如果flag等于1,则打印该行。

有关更详细的说明和示例,以及显示或不显示模式的情况,请参阅如何select两种模式之间的线? 。

使用sed

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

-n选项表示默认情况下不打印。

该模式查找只包含abcmno ,然后执行{ ... } 。 第一个操作删除abc行; 第二个mno线; 并打印剩余的行。 您可以根据需要放松正则expression式。 abc .. mno范围以外的任何行都不会被打印出来。

这可能适用于你(GNU sed):

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

删除从abcmno开始的行之间的所有行

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

高尔夫比ppotong更好的两个字符{//!b};d

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

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

这似乎是POSIX :

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

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

像这样的东西适合我:

file.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解决scheme比我的更好/更漂亮。

Don_crissti的答案只显示两个匹配模式之间的文本 ?

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

这比AWK的应用程序高效得多,请看这里 。

从以前的响应链接中,为我做的,在Solaris上运行ksh的是:

 sed '1,/firstmatch/d;/secondmatch/,$d'