如何运行 find -exec?

rip*_*234 675 find

我想在当前目录中找到包含文本“chrome”的文件。

$ find . -exec grep chrome
find: missing argument to `-exec'
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

小智 1016

您错过了 a ;(在此处转义\;以防止 shell 对其进行解释)或 a+和 a {}

find . -exec grep chrome {} \;
Run Code Online (Sandbox Code Playgroud)

或者

find . -exec grep chrome {} +
Run Code Online (Sandbox Code Playgroud)

find将执行grep并替换{}为找到的文件名。之间的差;+是与;单个grep每个文件命令而用执行+尽可能多的文件尽可能给出作为参数传递给grep在一次。

  • 如果你使用\; 结束构造 grep 一次传递一个文件,因此默认情况下它不显示文件名,只显示匹配的行。要获取文件列表,请在 find 构造中添加使用 `grep -ls`。 (39认同)
  • `找到。-exec grep foo {} +` 将显示这样的输出`./dir/file.py:from foo import bar` (15认同)
  • `找到。-exec grep foo {} \;` 将显示像这样的输出 `from foo import bar` (14认同)
  • `找到。-exec grep -l foo {} +` 将显示像这样的输出 `./dir/file.py` (12认同)
  • `找到。-exec grep -l foo {} \;` 将显示像这样的输出 `./dir/file.py` (11认同)
  • 在 `fish` shell 中,你也需要转义大括号 `find 。-exec grep chrome \{\} \;` (3认同)
  • 或者你可以只是`find . -print -exec grep chrome \;` 让 `find` 打印出文件名... (2认同)

Cal*_*leb 61

您根本不需要为此使用find;grep 能够处理从当前目录中所有内容的全局列表中打开文件:

grep chrome *
Run Code Online (Sandbox Code Playgroud)

...甚至递归文件夹及其下的所有内容:

grep chrome . -R
Run Code Online (Sandbox Code Playgroud)

  • 如果扩展超过 ARG_MAX,grep 将窒息。-R 将访问所有内容,而使用 find one 可以更轻松地添加原语以排除某些文件(-name 等),甚至不访问子树(-prune)。 (27认同)
  • 好点@Mel。我的观点是,当 `grep` 可以完成这项工作时,通过引入 `find`,询问方很可能使事情变得比他们需要的更复杂,但在某些情况下,使用 find 来完善 tine 会更有效去grep之前的文件列表。 (8认同)
  • @Mel `grep` 在这种情况下不会窒息,`exec` 会。 (4认同)
  • @Yaba 我的回答说明了如何处理分布在子目录中的文件的情况。 (3认同)
  • @DaCheetah这是一个误解——上面的评论与“find -exec”无关。这里的“exec”指的是直接调用“execve”系统调用的libc函数(例如“exec{ve,vp,lp,...}”),而不是“find -exec”,后者先进行自己的操作。关键是“grep”甚至从来没有看到被它们阻塞的参数,是内核拒绝了它。 (3认同)

小智 19

find . | xargs grep 'chrome'
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

find . | xargs grep 'chrome' -ls
Run Code Online (Sandbox Code Playgroud)

第一个显示文件中的行,第二个只列出文件。

Caleb 的选择更简洁,击键次数更少。

  • `xargs` 的问题在于它期望以一种特殊的方式引用它的输入,而 `find` 不会产生。所以`找到... | 如果文件名包含空格或 `\'"`,则 xargs ...` 不起作用。 (13认同)
  • @Caleb:让`xargs` 处理Linux 文件名的唯一100% 可靠的方法是`find ... -print0 | xargs -0`,使用 NUL 作为分隔符。替代方案 - `xargs -d '\n'` 使用换行符作为分隔符,99% 的可靠性。 (12认同)
  • @Gilles 您可以通过使用诸如 `find 之类的东西来解决这个问题。| xargs -n1 -iX grep "X" 'chrome'` 以便一次输入一个参数并引用。显然,这是处理这个例子的一种极其低效的方式,但对于某些情况来说,这很好。 (3认同)

Ask*_*arn 10

查找是一种方法,您可以尝试,the_silver_searcher然后您需要做的就是

ag chrome
Run Code Online (Sandbox Code Playgroud)

它将在所有文件(包括子目录)中搜索 chrome,并且比 find 更快


小智 6

这是我通常如何使用 find/exec 的示例...

find  . -name "*.py" -print -exec fgrep hello {} \;
Run Code Online (Sandbox Code Playgroud)

这将递归搜索所有 .py 文件,并为每个文件打印出文件名和 fgrep 在该(每个)文件上的“hello”。输出看起来像(今天刚运行了一个):

./r1.py
./cgi-bin/tst1.py
print "hello"
./app/__init__.py
./app/views.py
./app/flask1.py
./run.py
./tst2.py
print "hello again"
Run Code Online (Sandbox Code Playgroud)


小智 5

要查看文件列表而不是行:

grep -l "chrome" *
Run Code Online (Sandbox Code Playgroud)

或者:

grep -r -l "chrome" .
Run Code Online (Sandbox Code Playgroud)