我知道 可以-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 … +
尽可能使用该表单,因为它更简单,并且出于这里其他答案中提到的原因(例如,无需考虑太多即可处理奇怪的文件名)。