在查找结果中使用 xargs 时,如何处理文件名中的空格?

abe*_*ger 31 find grep pipe xargs

我的一个常见做法是对某种类型的所有文件执行 grep,例如,找到所有包含“rumpus”一词的 HTML 文件。为此,我使用

find /path/to -name "*.html" | xargs grep -l "rumpus"
Run Code Online (Sandbox Code Playgroud)

有时,find会返回名称中带有空格的文件,例如my new file.html. 但是,当xargs将此传递给grep时,我收到以下错误:

grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我可以看到这里发生了什么:管道或xargs正在将空格视为文件之间的分隔符。但是,对于我的一生,我无法弄清楚如何防止这种行为。可以用find+完成xargs吗?还是我必须使用完全不同的命令?

use*_*517 31

find ... -print0 | xargs -0 ...
Run Code Online (Sandbox Code Playgroud)

例如

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"
Run Code Online (Sandbox Code Playgroud)

从查找手册页

-print0
          True; print the full file name on the standard  output,  followed
          by  a  null  character  (instead  of  the  newline character that
          ‘-print’ uses).  This allows file names that contain newlines  or
          other  types  of  white space to be correctly interpreted by pro-
          grams that process the find output.  This option  corresponds  to
          the ‘-0’ option of xargs.
Run Code Online (Sandbox Code Playgroud)


sci*_*rus 17

您不需要使用xargs,因为find可以自己执行命令。这样做时,您不必担心 shell 解释名称中的字符。

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +
Run Code Online (Sandbox Code Playgroud)

从查找手册页

-exec command {} +
这个 -exec 动作的变体在选定的文件上运行指定的命令,但是命令行是通过在每个选定的文件名后附加来构建的;命令的总调用次数将远小于匹配文件的数量。命令行的构建方式与 xargs 构建其命令行的方式非常相似。命令中只允许出现一个“{}”实例。该命令在起始目录中执行。


小智 8

如果您系统上的 find 和 xarg 版本不支持-print0-0切换(例如 AIX find 和 xargs),您可以使用以下命令:

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"
Run Code Online (Sandbox Code Playgroud)

这里 sed 将负责转义 xargs 的空间。