spe*_*ong 18 command-line grep sed
我使用以下命令递归搜索多个文件,并在找到该字符串的每个文件中查找行号。
grep -nr "the_string" /media/slowly/DATA/lots_of_files > output.txt
Run Code Online (Sandbox Code Playgroud)
输出如下:
/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.
Run Code Online (Sandbox Code Playgroud)
如上所示,输出包括文件名、行号和该行中的所有文本,包括字符串。
我还想出了如何使用以下命令仅打印包含字符串的文件的特定行:
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
Run Code Online (Sandbox Code Playgroud)
我通过读取行号和文件名手动创建了上述命令
这是我的问题。
Q1a
有没有办法将两个步骤合并为一个命令?我正在考虑将行号和文件名输入 sed 并打印该行。我对生成 grep 输出的顺序有问题。
Q1b
与上面相同,但还要打印包含字符串的行之前的 2 行和之后的 2 行(共 5 行)?我正在考虑将行号和文件名输入 sed 并以某种方式打印所有必需的行。
十分感谢。
che*_*rdt 18
如果我正确理解了这个问题,您可以使用一个 grep 命令来完成此操作。
对于 Q1a,您的grep输出可以使用 抑制文件名-h,例如:
grep -hnr "the_string" /media/slowly/DATA/lots_of_files > output.txt
Run Code Online (Sandbox Code Playgroud)
对于 Q1b,您的grep输出可以包括使用-Aand匹配行之前和之后的行-B,例如:
grep -hnr -A2 -B2 "the_string" /media/slowly/DATA/lots_of_files > output.txt
Run Code Online (Sandbox Code Playgroud)
输出将包含匹配项之间的分隔符,您可以使用 来抑制它--no-group-separator,例如:
grep -hnr -A2 -B2 --no-group-separator "the_string" /media/slowly/DATA/lots_of_files > output.txt
Run Code Online (Sandbox Code Playgroud)
请注意,输出使用不同的分隔符来匹配行 ( :) 和上下文行 ( -)。
据我所知,你的第一个问题可以通过grep不同的方式来回答。当您向它发送文件列表(或使用-r或进行递归的目录-R)时,它将始终输出找到匹配项的文件以及行号。您可以使用如下结构来解决这个问题:
find /path/to/files -type f | xargs grep -n 'the_pattern'
Run Code Online (Sandbox Code Playgroud)
至于你的第二个问题,如果你想查看比赛之前和之后的行,你可以使用-C(for C ontext) 开关:
grep -C2 'pattern' /path/to/file # displays the two lines before and after a match
Run Code Online (Sandbox Code Playgroud)
相关的-C有-A(for A fter) 和-B(for B before),它们分别只给出匹配之后或之前指定的行数。
您可以这样组合两个答案:
find /path/to/files -type f | xargs grep -n -C2 'the_pattern'
Run Code Online (Sandbox Code Playgroud)
至于你的问题sed,你给出的例子只有在你已经知道行号的情况下才有效。您还可以执行以下操作:
sed -n '/the_pattern/p' /path/to/files/*
Run Code Online (Sandbox Code Playgroud)
(但不会递归到子目录)