Linux 两种图案中间的纹

Linux 两种图案中间的纹,linux,shell,unix,awk,sh,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 我在web awk'/patterns1/,/patterns2/'path>text.txt中找到了 但是我只需要输出中间的第三种模式。 < P>这个AWK应该工作: awk '$1=="Start"{ok++}

嗨,我正在寻找一个awk,可以找到两个模式,并打印它们之间的数据到 文件只有在中间,中间有第三种模式。 例如:

Start
1
2
middle
3
End
Start
1
2
End

And the output will be:
Start
1
2
middle
3
End
我在web awk'/patterns1/,/patterns2/'path>text.txt中找到了 但是我只需要输出中间的第三种模式。

< P>这个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 0{
a[b++]=$0
}
$1==“中等”{
嗯++
}
$1==“结束”{
如果(确定>1)

对于(i=0;i只需将一些标志与
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
}
/Start/{
开始标志=1
}
/中/{
中旗=1
}
启动标志{
n=NR;
行[NR]=$0
}
/完(完){
如果(开始标志和中间标志)

对于(i=n;i,这里是一个不带标志的解决方案:

$ awk 'BEGIN{RS="End"}/middle/{printf "%s", $0; print RT}'  file
Start
1
2
middle
3
End
说明:
RS
变量是记录分隔符,因此我们将其设置为“End”,以便每个记录都用“End”分隔


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

awk '/middle/{printf "%s%s\n",$0,RT}' RS="End" file
编辑: 添加了开始标签的测试

awk '/Start/ && /middle/{printf "%s%s\n",$0,RT}' RS="End" file

这将适用于任何现代awk:

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

将RS设置为“结束”的解决方案GAWK是特定的,这可能是好的,但它确实值得一提。

烦琐,但可行。您需要在开始和结束之间保存材料,当您遇到中间时,注意保存的材料应该被打印,并且在您处理结束时,查看是否保存了打印的材料。我没有时间将其还原为。立即编码。(识别开始后,将每个
$0
保存到一个数组中;结束时停止保存,如果合适,打印数组并清除数组。)此外,在开始和结束之间是否可以有任何数据行?或者它始终是一系列的开始..结束行,但只需要打印其中一些。可以为空,但我只需要具有中间模式的一行,因此文件可以包含:
Start
1
middle
2
End
Junk
<代码>
开始
3
4
结束
?输出中不应包含
垃圾
?只应回显前5行?垃圾行或空行可以位于中间包提供的开始和结束内…但我认为它需要对其工作原理进行一些解释ks。这没有考虑到
开始
它只打印同时包含
中间
结束
的记录。您还在记录后添加了一个额外的换行符。@JonathanLeffler在问题级注释的OP中添加了一个解释请参见我的辅助问题。如果没有其他内容,这会很好地工作开始..结束序列;如果有其他数据必须删除,则不太热门。但是,如果数据允许它工作,则是个好主意。这不会检查
Start
更新我的帖子以测试
Start
awk '/Start/{f=1;rec=""} f{rec=rec $0 ORS} /End/{if (rec~/middle/) printf "%s",rec}' file