如何查找包含字符串的行,然后打印这些特定行和其他内容

如何查找包含字符串的行,然后打印这些特定行和其他内容

我使用以下命令递归搜索多个文件并查找每个文件中找到该字符串的行号。

    grep -nr "the_string" /media/slowly/DATA/lots_of_files > output.txt

输出如下:

    /media/slowly/DATA/lots_of_files/lots_of_files/file_3.txt:3:the_string
    /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt:6:the_string is in this sentence.
    /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt:9:the_string is in this sentence too.

如上所示,输出包括文件名、行号以及该行中的所有文本(包括字符串)。

我还弄清楚了如何使用以下命令仅打印包含字符串的文件的特定行:

    sed '3!d' /media/slowly/DATA/lots_of_files/lots_of_files/file_3.txt > print.txt
    sed '6!d' /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt >> print.txt
    sed '9!d' /media/slowly/DATA/lots_of_files/lots_of_files/file_7.txt >> print.txt

我通过读取行​​号和文件名手动创建了上述命令

这是我的问题。

Q1a

有没有办法将这两个步骤合并为一个命令?我正在考虑将行号和文件名通过管道传输到 sed 中并打印该行。我对 grep 输出的生成顺序有疑问。

Q1b

与上面相同,但还打印包含字符串的行之前的 2 行和之后的 2 行(总共 5 行)?我正在考虑将行号和文件名通过管道传输到 sed 中并以某种方式打印所有必需的行。

十分感谢。

答案1

如果我正确理解了这个问题,您可以使用一个 grep 命令来完成此任务。

对于 Q1a,您的grep输出可以使用 抑制文件名-h,例如:

grep -hnr "the_string" /media/slowly/DATA/lots_of_files > output.txt

对于 Q1b,您的grep输出可以包含使用 和 匹配的行之前和之后的行-A-B例如:

grep -hnr -A2 -B2 "the_string" /media/slowly/DATA/lots_of_files > output.txt

输出将在匹配项之间包含分隔符,您可以使用 抑制该分隔符--no-group-separator,例如:

grep -hnr -A2 -B2 --no-group-separator "the_string" /media/slowly/DATA/lots_of_files > output.txt

请注意,输出使用不同的分隔符来匹配行 ( :) 和上下文行 ( -)。

答案2

据我所知,您的第一个问题可以通过grep不同的方式回答。当您向它发送文件列表(或要使用-r或递归的目录-R)时,它将始终输出在哪个文件中找到匹配项以及行号。您可以使用以下构造来解决这个问题:

find /path/to/files -type f | xargs grep -n 'the_pattern'

至于你的第二个问题,如果你想查看比赛前后的台词,你可以使用-C(forContext)开关:

grep -C2 'pattern' /path/to/file # displays the two lines before and after a match

相关的-C-A(对于A之后)和-B(对于before),它仅分别给出匹配之后或之前指定的行数。

您可以这样组合两个答案:

find /path/to/files -type f | xargs grep -n -C2 'the_pattern'

至于你关于的问题sed,你给出的示例只有在你已经知道行号的情况下才有效。你也可以这样做:

sed -n '/the_pattern/p' /path/to/files/*

(但不会递归到子目录)

答案3

find /media/slowly/DATA/lots_of_files -type f -exec grep -h -C2 'the_pattern' {} +

这将找到 /media/slowly/DATA/lots_of_files 目录下的文件(而不是目录或链接)。它将它们分组(这十年不需要 xargs)并对它们运行 grep。 grep 不会打印文件名 (-h),但会在匹配行之前和之后给出 2 行上下文(-C2,使用 -A 和 -B 进行更精确的控制)。

与 @cherdt 中的命令相比,此命令的优点是您可以在 find 命令中添加其他过滤器,例如您可以选择不进入类似目录.git

相关内容