我有一个如下所示的文件
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/p
B
如果其中有 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