如何在 BSD 查找中使用 xargs?

How to use xargs with BSD find?

使用 GNU find,很容易通过管道传输到 xargs。一个典型的(没用的)例子:

find /var/log -name "*.log" | xargs dirname

这returns包含一些日志文件的所有目录名。

与 BSD find 相同的命令不起作用,结尾为:

usage: dirname path

xargs 无法将文件列表条目传递给 dirname

BSD find 的联机帮助页提到 -exec-execdir 选项,说明 "This behaviour is similar to that of xargs(1)."

-exec utility [argument ...] {} + Same as -exec, except that ``{}'' is replaced with as many pathnames as possible for each invocation of utility. This behaviour is similar to that of xargs(1).

-execdir utility [argument ...] {} + Same as -execdir, except that ``{}'' is replaced with as many pathnames as possible for each invocation of utility. This behaviour is similar to that of xargs(1).

每次我求助于这两个标志时,我都必须再次阅读文档。我好像想不起来它们的用法了!此外,我还关心跨 GNU/BSD 系统的脚本可移植性,基本上是 Linux、Open/FreeBSD 和 MacOS。

有什么方法可以将 BSD find 传输到 xargs,或者 -exec 真的是唯一的选择吗?

GNU 和 FreeBSD 版本的 xargs 都支持将字符串从标准输入传递到命令作为 -I 标志的一部分的方法。您只需要

find /var/log -name "*.log" | xargs -I {} dirname -- "{}"

GNU xargs 页面将标志描述为

-I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input.

这提供了使用 -exec-execdir 的替代方法。但是,话虽如此,使用 -exec 对您的情况来说并不太复杂。

find /var/log -name "*.log" -type f -exec dirname "{}" \;