模式匹配和 grep 一起

模式匹配和 grep 一起

我有一个如下所示的文件

Event1
A
B
C
Event2
CC
CC
DD
Event1
E
N
D
Event2 

现在我可以在事件 1 和事件 2 之间进行 sed,并且能够获取它们之间的所有行,但我想要的是,如果 Sed 仅当事件 1 和事件 2 之间的行具有“B”作为内容时才能输出。所以我的输出看起来像

Event1
A
B
C
Event2

答案1

sed -n '/Event1/,/Event2/H;/Event2/{x;/B/p}' filename

解释:

  • sed 程序有两部分:/Event1/,/Event2/H/Event2/{x;/B/p}
  • 第一部分:/Event1/,/Event2/匹配介于Event1和之间的所有行Event2。将H所有这些行放入所谓的“保留空间”中。
  • 第二部分:/Event2/{x;/B/p}如果行包含Event2则执行命令组{x;/B/p}
  • 命令组也有两部分:x/B/p
  • x将“保留空间”中的所有内容放入“模式空间”中。
  • /B/pB如果其中有 a 则打印模式空间。

人类语言的想法是:记下Event1和之间的每一行Event2。如果您看到了Event2,请查看您刚刚注意到的所有行。如果其中有则B打印。否则忽略。


注意上面的 sed 程序有一个“bug”。

如果输入如下所示:

Event1x
A
B
C
Event2x
CC
CC
DD
Event1y
E
N
D
Event2y
CC
CC
DD
Event1z
X
B
X
Event2z

输出将如下所示:

$ sed -n '/Event1/,/Event2/H;/Event2/{x;/B/p}' foo

Event1x
A
B
C
Event2x
Event2y
Event1z
X
B
X
Event2z

请注意Event2y和 第一个空行。这是因为 sed 的特性。

sed 程序的此修改将 替换Event2y为空行。这与第一个空行的原因基本相同。

sed -n '/Event1/,/Event2/H;/Event2/{s/.*//;x;/B/p}' filename

输出示例

$ sed -n '/Event1/,/Event2/H;/Event2/{s/.*//;x;/B/p}' filename

Event1x
A
B
C
Event2x

Event1z
X
B
X
Event2z

空行可以用更多的 sed-fu 来修复,但我需要更多的声誉点来解决这个问题。


了解更多 sed!!1

相关内容