2016-03-28 31 views
0

喜文件夾後後,我找到文件,並用雙引號用下面的命令附上自己的名字:的grep無法讀取文件名找到空間

FILES=$(find . -type f -not -path "./.git/*" -exec echo -n '"{}" ' \; | tr '\n' ' ')

我的for循環裏面用grep某個詞做每個匹配的文件中找到:

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。完美的作品!

回答

2

問題是您的數組包含文字由文字"引號包圍。

但更糟糕的是,find-exec cmd {} \;分別對每個文件執行cmd,效率低下。正如@TomFenech在評論中提到的那樣,您可以使用-exec cmd {} +儘可能在單個cmd調用內搜索儘可能多的文件。

遞歸搜索的更好方法通常是讓find輸出文件名進行搜索,並將其結果輸出到xargs以便儘可能多地在文件名中進行搜索。分別使用-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,將模式視爲字符串文字。

+0

如果我確實想要一個與正則表達式不匹配的文件列表,那麼**又**? – Sanandrea

+0

'-L'選項列出文件不匹配。 –

+0

最後一個問題,第二個選項列出文件中的(非)匹配文件,是否可以用結果構建一個數組?所以我不需要閱讀文件的內容,然後刪除它。 – Sanandrea