awk中提取与至少匹配

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/ 
+0

什么是这里的逻辑积累线?你还有其他的例子吗? a和c总是出现两次?它可以有多个块? – fedorqui

+0

开始模式和停止模式匹配几行,但我只想要中间部分。假设我们有'a \ na \ n \ nb \ nc \ nc \ nc \ n',我想要获得'a \ nb \ nc \ n' – bitweaver

+0

将输出管道到'uniq'以摆脱重复。 – Barmar

你不能用范围表达式来做到这一点。您需要匹配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==NRIdiomatic 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/ 
+0

不应该是'> ='和' Barmar

+0

@Barmar你是对的。修正了,谢谢! – fedorqui

另一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/