我的一个常见做法是对某种类型的所有文件执行 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 的空格。