您好,我找到文件后用双引号将其名称用以下命令括起来:
FILES=$(find . -type f -not -path "./.git/*" -exec echo -n '"{}" ' \; | tr '\n' ' ')
我做一个for循环来grep每个匹配find的文件中的某个单词:
for f in $FILES; do grep -Eq '(GNU)' $f; done
但是grep会抱怨它找不到文件或目录的每个条目:
grep: "./test/test.c": No such file or directory
见图:
而echo $FILES
产生:
"./.DS_Store" "./.gitignore" "./add_license.sh" "./ads.add_lcs.log" "./lcs_gplv2" "./lcs_mit" "./LICENSE" "./new test/test.js" "./README.md" "./sxs.add_lcs.log" "./test/test.c" "./test/test.h" "./test/test.js" "./test/test.m" "./test/test.py" "./test/test.pyc"
修改 找到了答案here。效果很好!
答案 0 :(得分:2)
问题是您的数组包含由文字"
引号包围的文件名。
但更糟糕的是,find
-exec cmd {} \;
分别为每个文件执行cmd
,这可能效率低下。正如@TomFenech在评论中所提到的,您可以使用-exec cmd {} +
在单个cmd
调用中搜索尽可能多的文件。
更好的递归搜索方法通常是让find
输出文件名进行搜索,并将结果传递给xargs
,以便在尽可能多的文件名内部进行grep。分别使用-print0
和-0
来正确支持带空格和其他分隔符的文件名,方法是将结果拆分为空字符 - 这样您就不需要引号,从而减少了错误的可能性。
这样的事情:
find . -type f -not -path './.git/*' -print0 | xargs -0 egrep '(GNU)'
但是在你的问题中,你在循环中有grep -q
,所以我怀疑你可能正在寻找每个文件的错误状态(找到/找不到)?如果是这样,您可以使用-l
代替-q
来制作grep
列表匹配的文件名,然后将该输出传输/发送到您需要结果的位置。
find . -print0 | xargs -0 egrep -l pattern > matching_filenames
另请注意,grep -E
(或egrep
)使用扩展正则表达式,这意味着括号创建正则表达式组。如果您要搜索包含(GNU)
的文件(使用括号),请改用grep -F
或fgrep
,将模式视为字符串文字。