您好,我正在寻找一个能够查找两个模式并在它们之间找到数据的awk程序,只有当中间存在第三个模式时才将其打印到文件中。例如:
Start
1
2
middle
3
End
Start
1
2
End
And the output will be:
Start
1
2
middle
3
End
我在网上发现了这样一个命令: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/
过滤器过滤包含“middle”的记录,并对匹配的记录打印当前记录和分隔符print RT
。Start
,它只打印包含 middle
和 End
的记录。你还在记录后添加了一个额外的换行符。 - Chris Seymourawk '$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
中使用一些标志:
/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 用户000001。
awk '/middle/{printf "%s%s\n",$0,RT}' RS="End" file
编辑: 添加了开始标签测试
awk '/Start/ && /middle/{printf "%s%s\n",$0,RT}' RS="End" file
Start
。 - mschilli这适用于任何现代的awk:
awk '/Start/{f=1;rec=""} f{rec=rec $0 ORS} /End/{if (rec~/middle/) printf "%s",rec}' file
$0
保存在一个数组中;在结束时停止保存,如果适当则打印数组并清除数组。) - Jonathan LefflerStart
,1
,middle
,2
,End
,Junk
,<blank line>
,Start
,3
,4
,End
?而Junk
和<blank line>
不应该包含在输出中?只有前5行应该被回显? - Jonathan Leffler