我常见的做法之一是对所有types的文件执行greps,例如查找所有包含“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
我可以看到这里发生了什么:pipe道或xargs
将空间视为文件之间的分隔符。 但对于我的生活,我无法弄清楚如何防止这种行为。 可以用find
+ xargs
来完成吗? 或者我必须使用完全不同的命令?
使用
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.
你不需要使用xargs ,因为find可以自己执行命令。 当这样做的时候,你不必担心名字中的shell解释字符。
find /path/to -name "*.html" -exec grep -l "rumpus" '{}' +
从查找手册页
-exec命令{} +
-exec操作的这种变体在选定的文件上运行指定的命令,但命令行是通过在每个选定的文件名后加上来构build的; 该命令的总调用次数将远远less于匹配文件的数量。 命令行的构build方式与xargs构build其命令行的方式大致相同。 命令中只允许有一个“{}”实例。 该命令在起始目录中执行。
如果系统上的find和xarg版本不支持-print0
和-0
开关(例如AIX find和xargs),则可以使用以下命令:
find /your/path -name "*.html" | sed 's/ /\\ /g' | xargs grep -l "rumpus"
这里sed会照顾为xargs逃脱的空间。