两个图案之间的中间有图案的awk

时间:2013-08-19 17:33:46

标签: linux shell unix awk sh

您好我正在寻找一个可以找到两种模式并在它们之间打印数据的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 /'路径>的text.txt 但我只需要在中间输出第三个模式。

5 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:3)

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

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

说明:RS变量是记录分隔符,因此我们将其设置为“结束”,以便每个记录以“结束”分隔。

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

答案 2 :(得分:3)

修改了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

答案 3 :(得分:2)

这个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

答案 4 :(得分:2)

这适用于任何现代的awk:

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

将RS设置为“结束”的解决方案是特定的gawk,这可能没问题,但绝对值得一提。