如何在awk / sed中多次出现两个标记模式之间select行
使用awk
或sed
我怎样才能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>
在sed
或awk
有什么方法可以重复执行,直到文件结束?
使用带有标志的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文本mno
时mno
设置flag
。 - 最后一个
flag
是一个带有默认行为的模式,即print $0
:如果flag
等于1,则打印该行。
有关更详细的说明和示例,以及显示或不显示模式的情况,请参阅如何select两种模式之间的线? 。
使用sed
:
sed -n -e '/^abc$/,/^mno$/{ /^abc$/d; /^mno$/d; p; }'
-n
选项表示默认情况下不打印。
该模式查找只包含abc
到mno
,然后执行{ ... }
。 第一个操作删除abc
行; 第二个mno
线; 并打印剩余的行。 您可以根据需要放松正则expression式。 abc
.. mno
范围以外的任何行都不会被打印出来。
这可能适用于你(GNU sed):
sed '/^abc$/,/^mno$/{//!b};d' file
删除从abc
和mno
开始的行之间的所有行
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'