使用 find (1) 和 grep (1) 查找包含特定字符串的文件

H.R*_*iee 107 bash find

find . -type f -print -exec cat {} \; | grep some string

上面的命令不打印文件路径。

我正在使用:Ubuntu, bash 4

小智 149

我用

grep "some string" . -R
Run Code Online (Sandbox Code Playgroud)

它工作得更快

ps

更复杂的用例

grep -HiRE "some string|other string" . #H for file printing, i for case-insensitive, R for recursive search, E for regex 
Run Code Online (Sandbox Code Playgroud)

阅读参数我的解释

grep --help | grep -- -i
Run Code Online (Sandbox Code Playgroud)

  • 如果你想要行号,还有`-n`。+1 为简化答案。 (22认同)
  • 老实说,这应该标记为正确答案。当前选定的一个完全详细说明了其他内容。 (2认同)

gle*_*man 118

那是因为您正在输入grep一个恰好包含文件名的文本流。由于您没有提供文件名作为 grep 的参数,因此无法推断匹配的行来自哪个文件。使用xargs

find . -type f -print | xargs grep "some string"
Run Code Online (Sandbox Code Playgroud)

由于您有 GNU find/xargs,这是 xargs 读取文件名的一种更安全的方式:

find . -type f -print0 | xargs -0 grep "some string"
Run Code Online (Sandbox Code Playgroud)

如果您只想要具有匹配行而不显示匹配行的文件名:

find . -type f -print0 | xargs -0 grep -l "some string"
Run Code Online (Sandbox Code Playgroud)


Pit*_*tto 18

我经常在复杂的文件夹结构中搜索源代码,我发现使用以下方法很有用:

cd /your/folder/
grep -rHino "your string"
Run Code Online (Sandbox Code Playgroud)

使用这些参数,不使用 find,我获取文件完整路径和包含指定 string行号

这也很容易记住,因为它的bash通过搜索像ES犀牛:)

我将用一个简单的例子来展示这是如何工作的。

让我们使用 cat 显示文件的内容:

jeeves ~ # cat fw.stop
#!/bin/sh
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
Run Code Online (Sandbox Code Playgroud)

让我们递归搜索所有包含字符串“iptables -P”的文件:

jeeves ~ # grep -rinHo "iptables -P"
fw.stop:9:iptables -P
fw.stop:10:iptables -P
fw.stop:11:iptables -P
Run Code Online (Sandbox Code Playgroud)

正如你在输出中看到的,我们有filename:hit row:searched string

以下是所用参数的更详细说明:

-r对于每个目录操作数,递归读取并处理该目录中的所有文件。遵循命令行上的符号链接,但跳过递归遇到的符号链接。请注意,如果没有给出文件操作数,grep 将搜索工作目录。这与“--directories=recurse”选项相同。

-i忽略大小写。

-n在其输入文件中使用从 1 开始的行号为每一行输出添加前缀。(-n 由 POSIX 指定。)

-H打印每个匹配项的文件名。这是要搜索多个文件时的默认设置。

-o只打印匹配行的匹配(非空)部分,每个这样的部分在一个单独的输出行上。输出行使用与输入相同的分隔符,如果还使用了 -z (--null-data),则分隔符为空字节(请参阅其他选项)。

  • 我唯一要添加的是“b”选项,它也显示字节偏移位置,尽管“rHinob”不太吸引人;) (2认同)