我正在运行 Mac 10.7.5。在终端中,我将使用此命令查找包含字符串的文件
find src/main -name "*" | xargs grep -i 'mystring'
但是当文件包含空格时,我会得到如下结果
grep: images/mystuff/essential-questions-selected-arrow-ela: No such file or directory
grep: 5.24.38: No such file or directory
grep: PM.png: No such file or directory
上述示例中的实际文件是“essential-questions-selected-arrow-ela 5.24.38 PM.png”即使被搜索的文件包含空格,我该如何成功运行上述命令?
答案1
如果你想使用find
输出xargs
,推荐的方法是使用NUL
字符来分隔每个文件名:
find src/main -name "*" -print0 | xargs -0 grep -i 'mystring'
原因是 shell(xargs
特别是)通常分裂论点(或在 的情况下为 输入xargs
)基于空白,即空格、制表符和换行符。一旦使用-0
,xargs
将读取由 分隔的每个字段NUL
,这就是输出find -print0
。
这将在 GNUfind
以及xargs
OS X 中包含的版本中起作用。其他版本可能没有这些选项,因为它们不是 POSIX 所要求的。
但话又说回来,这其实不是必要的。"*"
名称模式扩展到所有可能的名称。grep
可以自行递归,因此所需的只是:
grep -ri 'mystring' src/main
在 Bash 4 中(默认情况下不随 OS X 一起提供),您还可以执行递归遍历,例如遍历所有.txt
文件,使用选项globstar
:
shopt -s globstar
grep -i 'mystring' **/*.txt
答案2
到目前为止,执行此类操作最安全、最简单的方法是使用 find 的-exec
选项。来自man find
:
-exec utility [argument ...] ;
True if the program named utility returns a zero value as its exit status.
Optional arguments may be passed to the utility. The expression must be
terminated by a semicolon (``;''). If you invoke find from a shell you
may need to quote the semicolon if the shell would otherwise treat it as a
control operator. If the string ``{}'' appears anywhere in the utility
name or the arguments it is replaced by the pathname of the current file.
Utility will be executed from the directory from which find was executed.
Utility and arguments are not subject to the further expansion of shell
patterns and constructs.
-exec utility [argument ...] {} +
Same as -exec, except that ``{}'' is replaced with as many pathnames as
possible for each invo-cation invocationcation of utility. This behaviour
is similar to that of xargs(1).
换句话说,该-exec
选项将根据 find 的结果运行您提供的任何内容,替换{}
找到的每个文件(或目录)。因此,要 grep 特定字符串,您可以执行以下操作:
find src/main -name "*" -exec grep -i 'mystring' {} +
但是,这样也会找到目录并给出错误。请注意,它会起作用,当您尝试在目录上运行它时,它只会发出抱怨,使用 也会遇到同样的问题xargs
。您实际上在这里尝试做的是查找所有文件并且只查找文件。在这种情况下,不需要 ,-name '*'
因为find src/main
和 完全相同find src/main -name "*"
。因此,不要使用它,而是指定您只想查找文件:
find src/main -type f -exec grep -i 'mystring' {} +