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:]]/
)
您可以使用此表达式 ( 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
这个结果的线路返回。
看起来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 上写了很多答案;这个特别有一些额外的解释可能会有所帮助。
归档时间: |
|
查看次数: |
736 次 |
最近记录: |