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

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

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

find /path/to -name "*.html" | xargs grep -l "rumpus"

有时,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

我知道这是怎么回事:管道或xargs将空格视为文件之间的分隔符。但是,我实在想不出如何防止这种行为。可以用find+来实现xargs吗?还是我必须使用完全不同的命令?

答案1

使用

find ... -print0 | xargs -0 ...

例如

find /path/to -name "*.html"  -print0 | xargs -0  grep -l "rumpus"

从查找手册页

-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.

答案2

您不需要使用参数, 因为寻找可以自行执行命令。执行此操作时,您不必担心 shell 解释名称中的字符。

find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +

从查找手册页

-exec 命令 {} +
此 -exec 操作的变体在选定的文件上运行指定的命令,但命令行是通过在末尾附加每个选定文件名来构建的;命令的总调用次数将远少于匹配文件的数量。命令行的构建方式与 xargs 构建其命令行的方式大致相同。命令中只允许一个“{}”实例。命令在起始目录中执行。

答案3

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

find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"

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

相关内容