两个模式之间的Awk与中间的模式

嗨,我正在寻找一个awk,可以find两种模式,并打印到他们之间的数据文件,只是如果在中间有第三种模式。 例如:

Start 1 2 middle 3 End Start 1 2 End And the output will be: Start 1 2 middle 3 End 

我发现在Web awk'/ patterns1 /,/ patterns2 /'path> text.txt但我只需要输出中间的第三个模式。

这里是一个没有标志的解决方案:

 $ awk 'BEGIN{RS="End"}/middle/{printf "%s", $0; print RT}' file Start 1 2 middle 3 End 

说明: RS变量是记录分隔符 ,所以我们将其设置为“End”,以便每个记录由“End”分隔。

然后我们使用/middle/ filter过滤包含“middle”的记录,对于匹配的记录,我们使用$0打印当前记录,使用print RT

awk使用一些标志:

 /Start/ { start_flag=1 } /middle/ { mid_flag=1 } start_flag { n=NR; lines[NR]=$0 } /End/ { if (start_flag && mid_flag) for(i=n;i<NR;i++) print lines[i] start_flag=mid_flag=0 delete lines } 

修改了awk user000001

 awk '/middle/{printf "%s%s\n",$0,RT}' RS="End" file 

编辑:添加测试开始标记

 awk '/Start/ && /middle/{printf "%s%s\n",$0,RT}' RS="End" file 

这awk应该工作:

 awk '$1=="Start"{ok++} ok>0{a[b++]=$0} $1=="middle"{ok++} $1=="End"{if(ok>1) for(i=0; i<length(a); i++) print a[i]; ok=0;b=0;delete a}' file Start 1 2 middle 3 End 

扩展:

 awk '$1 == "Start" { ok++ } ok > 0 { a[b++] = $0 } $1 == "middle" { ok++ } $1 == "End" { if (ok > 1) for (i=0; i<length(a); i++) print a[i]; ok=0; b=0; delete a }' file 

这将适用于任何现代awk:

 awk '/Start/{f=1;rec=""} f{rec=rec $0 ORS} /End/{if (rec~/middle/) printf "%s",rec}' file 

将RS设置为“End”的解决方案是特定于gawk的,这可能很好,但绝对值得一提。