5

Hi i am looking for an awk that can find two patterns and print the data between them to a file only if in the middle there is a third patterns in the middle. for example:

Start
1
2
middle
3
End
Start
1
2
End

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

I found in the web awk '/patterns1/, /patterns2/' path > text.txt but i need only output with the third patterns in the middle.

4

5 回答 5

4

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

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

说明:RS变量是记录分隔符,所以我们设置为“End”,这样每条Record都用“End”分隔。

然后我们使用过滤器过滤包含“中间”的记录,/middle/对于匹配的记录,我们打印当前记录$0和分隔符print RT

于 2013-08-19T17:45:30.383 回答
3

修改了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
于 2013-08-19T18:06:27.643 回答
3

这个 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
于 2013-08-19T17:43:24.663 回答
3

只需使用一些标志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
}
于 2013-08-19T17:44:19.447 回答
2

这适用于任何现代 awk:

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

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

于 2013-08-19T19:21:42.077 回答