2016-03-28 3 views
0

Hi after I find the filesとenclose their nameを持つdouble quotesとthe following command:grep cannot read filename after find foldersとのspaces

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

I do a用loopにgrep a certain word inside

for f in $FILES; do grep -Eq '(GNU)' $f; done

をしかし、grepのは、それはファイルやディレクトリを見つけることができないことを、各エントリ文句:

を見つける一致する各ファイル

grep: "./test/test.c": No such file or directory

画像参照:echo $FILESが生成するのに対し、

enter image description here

を:

"./.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" 

EDIT は答えhereを見つけました。完璧に動作します!

答えて

2

問題は、配列にリテラル"の引用符で囲まれたファイル名が含まれていることです。

さらに悪いことに、find-exec cmd {} \;は、ファイルごとに個別にcmdを実行します。これは非効率的です。 @TomFenechのコメントで述べたように、-exec cmd {} +を使用して、できるだけ1つのcmd呼び出し内の多くのファイルを検索できます。

通常、再帰的検索では、出力ファイル名をfindに出力し、その結果をxargsにパイプして、できるだけ多くのファイル名を一緒にgrepします。 -print0-0をそれぞれ使用すると、スペースやその他の区切り文字を含むファイル名を正しくサポートすることができます。結果をヌル文字で分割することで、引用符を必要とせず、バグの可能性を減らすことができます。このような

何か:

find . -type f -not -path './.git/*' -print0 | xargs -0 egrep '(GNU)' 

は、しかし、あなたの質問にあなたがループ内grep -qを持っていたので、私はあなたがファイルごとに(/見つからないことが判明)エラー状態を探している可能性があり疑いますか?その場合は、-qの代わりに-lを使用して、grepに一致するファイル名のリストを作成し、その出力を必要な場所にパイプ送信することができます。

find . -print0 | xargs -0 egrep -l pattern > matching_filenames 

grep -E(またはegrep)は括弧は正規表現のグループを作成することを意味する、拡張正規表現を使用することに注意してください。 (GNU)(かっこ付き)を含むファイルを検索する場合は、代わりにgrep -Fまたはfgrepを使用します。パターンは文字列リテラルとして扱われます。

+0

正規表現と一致しないファイルのリストを取得したい場合はどうしますか? – Sanandrea

+0

'-L'オプションは、一致しないファイルをリストします。 –

+0

最後の質問では、2番目のオプションは、ファイル内の(一致しない)ファイルをリストします。結果を含む配列を作成することは可能ですか?だから、私はファイルの内容を読んだり、後でそれを削除する必要はありません。 – Sanandrea