找到带空格的文件夹后,grep无法读取文件名

时间:2016-03-28 13:02:33

标签: macos bash grep find

您好,我找到文件后用双引号将其名称用以下命令括起来:

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

见图:

enter image description here

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。效果很好!

1 个答案:

答案 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 -Ffgrep,将模式视为字符串文字。