如何在每次grep匹配之后显示行,直到其他特定匹配?


44

我知道通过使用"-A NUM"开关,我可以在每次比赛后打印特定数量的尾随行。我只是想知道是否有可能打印尾行,直到每次比赛后找到一个特定的单词。例如,当我搜索“单词A”时,我想查看包含“单词A”的行以及其后的行,直到包含“单词D”的行。

上下文:

Word A
Word B
Word C
Word D
Word E
Word F

命令:

grep -A10 'Word A'

我需要以下输出:

Word A
Word B
Word C
Word D

Answers:


73

似乎您想在' Word A'和' Word D'(包括两端)之间打印行。我建议您使用sed代替grep。它使您可以编辑一系列输入流,该输入流以所需的模式开始和结束。您应该只告诉sed打印范围内的所有行,而不要打印其他行:

sed -n -e '/Word A/,/Word D/ p' file

关于如何使其独占的任何技巧(对于任何一般情况,而不仅仅是OP)?
2013年

4
@ 2rs2ts使其排他,只需添加 | sed -e '1d;$d',即删除第一行和最后一行
holroy 2015年

如果要排除之间的所有行-也就是说,您只希望看到两个匹配项之外的行-则sed -n -e '/pattern A/,/pattern D/d; p'说:“从模式A删除到模式D,然后打印其他所有内容”。不幸的是,这场比赛是贪婪的。这意味着,如果模式A和D出现不止一次,则您将从第一个模式A 匹配到最后一个模式D。如果是这种情况,恐怕Perl或Python是您的朋友。
fbicknel

16

为什么不使用awk?

awk '/Word A/,/Word D/' filename

2
如果涉及大量文件,sed似乎可以更加有效地执行此操作。awk可能更容易记住,但是sed在我的脑海中似乎值得一记便条。
JimNim 2014年

1
如果awk与Word D落在同一行Word A,并且可能在其他地方(例如Word A Word D\nWord Dsed)将显示两行,而awk将显示一行,则awk更好。另外,仍然可以将awk与变量一起使用,例如awk -v _word="Word A" '$0 ~ _word,/Word D/' "/some/file",这样sed可能会更有效,但是当处理两个字符串的搜索可能或可能不在同一行时,awk绝对更可靠。
S0AndS0

似乎awk可以更好地处理文件包含A和的序列的情况,B而您只想捕获每个此类序列之间的内容。看来sed至少在我看来并没有遵循这些语义。
马坦

9
perl -lne 'print if /Word A/ .. /Word D/' file

要么

cat file | perl -lne 'print if /Word A/ .. /Word D/'

1
+1以抵抗过路降票。sed除非您需要Perl正则表达式的功能来选择定界线,否则我仍然会使用它。
2013年

在70年代写sed的人一定要感激:-)
Matan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.