如何在 grepped 之后获得第 n 行?

WoJ*_*WoJ 7 linux bash grep command-line

考虑以下文本文件

one 1
two 2
three 3
four 4
five 5
six 6
seven 7
eight 8
Run Code Online (Sandbox Code Playgroud)

我想访问匹配后的第二行four。这将是这条线

six 6
Run Code Online (Sandbox Code Playgroud)

然后将生成的行(因此上面的行)通过管道进行进一步处理(例如 a | cut -d' ' -f2)。

有没有办法在 bash 和其他典型实用程序中做到这一点?(否则我会用 Python 编写它)

编辑:在我的特定情况下,four(以该示例为例)的发生保证是唯一的。但是答案显示了有趣的扩展案例,而事实并非如此。

AFH*_*AFH 16

前两个答案没有任何问题,但我想我会让您意识到可以在一次sed调用中找到模式后的第三行:

sed -n "/four/ { n; n; p }" SourceData.txt
Run Code Online (Sandbox Code Playgroud)

因为单个程序完成工作,所以这比运行多个过滤器更有效。上面的命令在“four”的每个实例之后输出第三行,除非在匹配后的两行之一中再次出现这种情况(其他解决方案也不会以预期的方式处理这种情况);此外,如果模式位于文件的最后一行或倒数第二行,则不会生成任何输出,这可能是您想要的,也可能不是。

仅匹配第一个实例:

sed -n "/four/ { n; n; p; q }" SourceData.txt
Run Code Online (Sandbox Code Playgroud)

(请注意,通过在找到匹配项后立即结束扫描,此答案尽可能有效。)

我添加这个解决方案是因为它值得了解sed,尽管它的语法相当令人反感(正则表达式已经够糟糕了!),但它通常非常有用。本教程是一个很好的介绍。


Kam*_*ski 10

注意:此答案最初是在 OP 明确说明该模式仅出现一次之前编写的。它旨在不会错过任何事件(除非接近尾声,因此没有“之后的第 n 行”),我将就这样离开它。如果您确定只有一次出现,或者如果您只想找到第一个,您可以考虑其他一些立即停止并且不会徒劳地解析整个输入流/文件的解决方案。


如果两行前存在匹配,则此解决方案打印当前行。它与其他几个答案略有不同,因为它不会错过另一场比赛,即使它发生在上一场比赛之后不久。

awk -v delay=2 '{for (i=delay; i>=0; i--) t[i]=t[i-1]} /four/ {t[0]="m"} {if (t[delay]) print}'
Run Code Online (Sandbox Code Playgroud)

每当有匹配项时,信息就会存储在t[0]. 随着每一行,t数组被移位(包括移位t[-1]t[0]以重置 的值t[0])。如果数组表明两行前存在匹配,则打印该行。

您可以轻松设置不同的延迟(例如delay=7)或使用其他模式(例如/sda[[:digit:]]/

  • @justhalf 一方面:`awk` 是标准的 POSIX 工具,`python` 不是。 (2认同)

zx4*_*485 8

您可以使用此表达式 ( input.txt):

grep "four" -A 2 input.txt | tail -n 1
Run Code Online (Sandbox Code Playgroud)

输出是:

six 6
Run Code Online (Sandbox Code Playgroud)

grep,匹配线之后的两行被输出选项“-A 2”的状态。
tail选项“-n 1”规定,只有最后1这个结果的线路返回。

  • 请注意,这只适用于只有一场比赛,或者您只对最后一场比赛感兴趣。 (4认同)

Wil*_*ard 5

看起来ex是 POSIX 指定的可脚本化文件编辑器的一个很好的用例。

与 sed 和 awk 不同,ex它实际上为文件编辑而不是流编辑而设计的,并且能够在文件中前后移动。它实际上是vi编辑器的非可视化形式。

但这里的重要方面ex是能够链接地址。因此,参考特定文本模式后两行的行是微不足道的。

这是一个命令,它打印包含以下内容的行两行的所有行four

printf '%s\n' 'g/four/+2p' | ex file.txt
Run Code Online (Sandbox Code Playgroud)

ex在 Unix & Linux Stack Exchange 上写了很多答案;这个特别有一些额外的解释可能会有所帮助。