find -exec + 与 find | xargs:选择哪一个?

find -exec + 与 find | xargs:选择哪一个?

我知道 可以-exec选择+模仿 的行为xargs。是否存在您更喜欢其中一种形式而不是另一种形式的情况?

我个人更喜欢第一种形式,即使只是为了避免使用管道。我想开发者肯定find已经做了适当的优化。我对么?

答案1

安全地通过管道传输文件名xargs需要您find支持该-print0选项并且您xargs有相应的选项来读取它(--null-0)。否则,名称中包含不可打印字符、反斜杠、引号或空格的文件名可能会导致意外行为。另一方面,find -exec {} +是在POSIXfind规范,所以它是便携式的,并且它与 一样安全find -print0 | xargs -0,并且绝对比 更安全find | xargs。我会推荐绝不find | xargs没有做-print0

答案2

您可能想要链接调用来查找(曾经,当您了解到这是可能的,这可能是今天)。当然,这只有在您继续查找时才有可能。一旦你通过管道传输到 xargs,它就超出了范围。

小例子,两个文件 a.lst 和 b.lst:

cat a.lst
fuddel.sh
fiddel.sh

cat b.lst
fuddel.sh

这里没有技巧 - 只是事实是两者都包含“fuddel”,但只有一个包含“fiddel”。

假设我们不知道这一点。我们搜索一个符合 2 个条件的文件:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls
192097    4 -rw-r--r--   1 stefan   stefan         20 Jun 27 17:05 ./a.lst

好吧,也许您知道 grep 或其他程序将两个字符串作为条件传递的语法,但这不是重点。每个可以返回 true 或 false 的程序(给定文件作为参数)都可以在这里使用 - grep 只是一个流行的例子。

请注意,您可以关注查找-执行与其他查找命令一起使用,例如-ls或者-删除或类似的东西。请注意,delete 不仅可以执行 rm(删除文件)操作,还可以执行 rmdir(删除目录)操作。

只要没有另外指定(即带有开关-or(和括号(需要屏蔽))),这样的链就会被读取为命令的 AND 组合。

所以你不会离开查找链,这是一件很方便的事情。我没有看到使用 -xargs 的任何优势,因为您在传递文件时必须小心,这是 find 不需要做的事情 - 它会自动处理将每个文件作为单个参数传递给您。

如果您认为需要对发现的东西进行一些掩盖{} 大括号,请随时访问我的问题,要求提供证据。我的断言是:你不知道。

答案3

如果您使用该-exec ... ;形式(记住转义分号),则每个文件名运行该命令一次。如果使用-print0 | xargs -0,则每个文件名运行多个命令。您绝对应该使用该-exec +表单,它将多个文件放在一个命令行中,并且在涉及大量文件时速度要快得多。

using 的一大优点xargs是能够使用 并行运行多个命令xargs -P。在多核系统上,这可以节省大量时间。

答案4

关于性能,我认为这-exec … +会更好,因为它是一个完成所有工作的单一工具,但是GNU findutil 文档的一部分-exec … +在某些情况下可能效率较低:

[查找与-exec … +]可能比 的某些用途效率低xargs;例如,xargs允许在上一个命令仍在执行的同时构建新的命令行,并允许您指定多个要并行运行的命令。然而,该find ... -exec ... +结构具有广泛的可移植性的优点。 GNU findutils-exec ... +直到版本 4.2.12 才支持 ' '[2005 年 1 月];原因之一是-print0无论如何它已经有了“ ”动作。

我不太确定这意味着什么,所以我在聊天中询问德罗伯特解释为:

find可能可以在运行时继续搜索下一批文件-exec … +,但事实并非如此。
find … | xargs …确实如此,因为查找是一个不同的进程,并且它会一直运行直到管道缓冲区填满

(我自己格式化的。)

所以就是这样。但如果性能真的很重要,您就必须进行实际的基准测试,或者甚至问问自己是否愿意在这种情况下使用 shell。

在这个网站上,我认为最好建议人们-exec … +尽可能使用该表单,因为它更简单,并且出于这里其他答案中提到的原因(例如,无需考虑太多即可处理奇怪的文件名)。

相关内容