awk中提取与至少匹配
问题描述:
说我有一些行的文件两个模式之间的内容:awk中提取与至少匹配
a1 - first match /a/
b - other stuff
a2 - last match /a/
b
c - first match /c/
c - last match /c/
当我执行awk '/a/,/c/' file
我会得到
a1 - first match /a/
b - other stuff
a2 - last match /a/
b
c - first match /c/
我想要做的是让/ a /和/ c /之间的中间部分。但模式/ a /和/ c /匹配几行,在这些行之间还有一些其他的东西。所以我想知道是否有一个简单的方法来得到如下结果:
a2 - last match /a/
b
c - first match /c/
答
你不能用范围表达式来做到这一点。您需要匹配a
并开始收集变量中的行。如果遇到另一个a
,则必须清除该变量并重新开始。最后,当你看到c
时,你打印这个变量。
awk '/^a/ { var = $0; flag = 1; next }
flag { var = var "\n" $0 }
/^c/ && flag { print var; flag = 0; var = "" }' file
+0
我打算发布这个回答'awk'/^a/{f = 1; buf =“”} f {buf = buf $ 0 RS}/^ c/{printf“%s”,buf; F = 0; buf =“”}'文件“,但它几乎与你的一样,所以加1给你,而我的轻微的替代语法在评论中! –
答
既然你没有办法知道这是最后一次的模式出现,直到你读所有的文件,它可能是最好要经过两次:第一次获得行比赛,第二个数量来打印内的那些行:
awk 'FNR==NR && /^a/ {p1=FNR; next} # last match of /a/
FNR==NR && /^c/ && !p2 {p2=FNR; next} # first match of /c/
(FNR >= p1) && (FNR <= p2)' file file
使用特技FNR==NR
如Idiomatic awk描述来区分从第二个所述第一环路。
有了这个文件,这将返回:
$ awk 'FNR==NR && /^a/ {p1=FNR; next} FNR==NR && /^c/ && !p2 {p2=FNR; next} (FNR >= p1) && (FNR <= p2)' file file
a2 - last match /a/
b
c - first match /c/
答
另一awk
在一个阵列,而不是
$ awk '/^a/{delete a; c=0; p=1}
p{a[++c]=$0}
/^c/{for(k=1;k<=c;k++) print a[k]; exit}' file
a2 - last match /a/
b
c - first match /c/
什么是这里的逻辑积累线?你还有其他的例子吗? a和c总是出现两次?它可以有多个块? – fedorqui
开始模式和停止模式匹配几行,但我只想要中间部分。假设我们有'a \ na \ n \ nb \ nc \ nc \ nc \ n',我想要获得'a \ nb \ nc \ n' – bitweaver
将输出管道到'uniq'以摆脱重复。 – Barmar