获取pattern1之间的行或获取与pattern2匹配的行 - sed / awk

时间:2016-05-03 15:29:59

标签: regex awk sed

我有一个格式为的文件:

PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1
text don't want
text don't want
text don't want
PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1
text don't want
text don't want
text don't want
...

我可以使用sed。

获取PATTERN1的出现之间的文本
sed -n -e '/PATTERN1/,/PATTERN1/ p' my_file.txt

我也可以获得匹配PATTERN2的行。

sed -n -e '/PATTERN2/ p' my_file.txt

但是,我无法获得与这些模式中的任何一种相匹配的行。我想要的输出是

PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1
PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1

感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

您可以将两个-e命令附加在一起。它将为每一行执行它们

sed -n -e '/PATTERN1/,/PATTERN1/ p' -e '/PATTERN2/ p' my_file.txt

警告:如果/PATTERN2//PATTERN1/内匹配,则该行将被打印两次

还有一个更复杂的sed命令解决了上述问题:

sed -e '/PATTERN1/,/PATTERN1/ !{
    /PATTERN2/ !d
}'

在标记之间不要删除除PATTERN2之外的所有内容。换句话说,在标记之外,删除除PATTERN2之外的所有内容。

答案 1 :(得分:0)

您可以使用此awk命令:

awk '/PATTERN1/{p=!p} p || /PATTERN1|PATTERN2/' file

PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1
PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1

答案 2 :(得分:0)

为了可维护性,请勿多次测试相同的硬编码值(例如PATTERN1):

$ awk '/PATTERN1/{if (f) print; f=!f} f || /PATTERN2/' file
PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1
PATTERN2
PATTERN1
text I want
more text I want ...
PATTERN1

如果您希望将来PATTERN1替换为FOO,请使用上述代码,您只需在一个地方进行更改。

答案 3 :(得分:0)

易读的sed版本:

sed -n "/PATTERN2/p;/PATTERN1/,/PATTERN1/p"

我希望这会有所帮助。

  • -n默认情况下不打印
  • / PATTERN2 / singular match string
  • p打印
  • / PATTERN1 / first match string
  • ,介于
  • 之间的一切
  • / PATTERN1 / second match string
  • p打印