仅当此范围中包含另一个模式时,如何在两个模式之间打印一系列线条?
How to print a range of lines between two patterns only if another pattern is included in this range?
我正在 Linux 上处理文本文件。我希望仅当在这些行中找到另一个模式时才能够打印两个模式之间的所有行(包括找到模式的行)。
例如:
PatternStart
line1
line2
PatternInside
line3
line4
PatternEnd
PatternStart
line1
line2
line3
PatternEnd
我只想获取第一行,因为它包含 PatternInside。
现在,我所能做的就是用
提取边界图案之间的线条
awk '/PatternStart/,/PatternEnd/' file
但这会提取两行。
您可以使用
awk 'flag{
buf = buf [=10=] ORS;
if (/PatternEnd/ && buf ~ /PatternInside/)
{printf "%s", buf; flag=0; buf=""}
}
/PatternStart/{buf = [=10=] ORS; flag=1}' file
此处,/PatternStart/{buf = [=12=]; flag=1}'
找到与 PatternStart
模式匹配的行,开始将输出值写入 buf
,并设置标志。如果该标志为真,后续行将附加到 buf
,并且一旦有一行 PatternEnd
匹配并且 PatternInside
在 buf
中找到匹配项,则匹配被打印,buf
被清除并且标志被重置。
查看 online demo 产生
PatternStart
line1
line2
PatternInside
line3
line4
PatternEnd
这可能适合您 (GNU sed):
sed -n '/PatternStart/{:a;N;/PatternEnd/!ba;/PatternInside/p}' file
通过设置 -n
关闭隐式打印。
匹配 PatternStart
,追加后续行直到 PatternEnd
匹配,然后检查集合中的字符串 PatternInside
,如果是则打印集合。
使用保留的替代解决方案 space:
sed -n 'H;/PatternStart/h;/PatternEnd/{g;/PatternInside/p}' file
如果块之间有空行
$ awk -v RS= '/^PatternStart.*PatternInside.*PatternEnd$/' file
PatternStart
line1
line2
PatternInside
line3
line4
PatternEnd
我正在 Linux 上处理文本文件。我希望仅当在这些行中找到另一个模式时才能够打印两个模式之间的所有行(包括找到模式的行)。
例如:
PatternStart
line1
line2
PatternInside
line3
line4
PatternEnd
PatternStart
line1
line2
line3
PatternEnd
我只想获取第一行,因为它包含 PatternInside。 现在,我所能做的就是用
提取边界图案之间的线条awk '/PatternStart/,/PatternEnd/' file
但这会提取两行。
您可以使用
awk 'flag{
buf = buf [=10=] ORS;
if (/PatternEnd/ && buf ~ /PatternInside/)
{printf "%s", buf; flag=0; buf=""}
}
/PatternStart/{buf = [=10=] ORS; flag=1}' file
此处,/PatternStart/{buf = [=12=]; flag=1}'
找到与 PatternStart
模式匹配的行,开始将输出值写入 buf
,并设置标志。如果该标志为真,后续行将附加到 buf
,并且一旦有一行 PatternEnd
匹配并且 PatternInside
在 buf
中找到匹配项,则匹配被打印,buf
被清除并且标志被重置。
查看 online demo 产生
PatternStart
line1
line2
PatternInside
line3
line4
PatternEnd
这可能适合您 (GNU sed):
sed -n '/PatternStart/{:a;N;/PatternEnd/!ba;/PatternInside/p}' file
通过设置 -n
关闭隐式打印。
匹配 PatternStart
,追加后续行直到 PatternEnd
匹配,然后检查集合中的字符串 PatternInside
,如果是则打印集合。
使用保留的替代解决方案 space:
sed -n 'H;/PatternStart/h;/PatternEnd/{g;/PatternInside/p}' file
如果块之间有空行
$ awk -v RS= '/^PatternStart.*PatternInside.*PatternEnd$/' file
PatternStart
line1
line2
PatternInside
line3
line4
PatternEnd