私はこれを大量に使用し、私が達成しようとする改善は、grepで一致しないファイル名がエコーされるのを防ぐことです。これを行うためのより良い方法は何ですか?
for file in `find . -name "*.py"`; do echo $file; grep something $file; done
ベストアンサー1
find . -name '*.py' -exec grep something {} \; -print
ファイル名を印刷します後ろに一致する行。
find . -name '*.py' -exec grep something /dev/null {} +
一致する各行の前にファイル名を印刷します(/dev/null
私たちが追加した場合は一つ検索するファイルのみを渡す場合、file asと一致するとgrep
ファイル名は印刷されません。 GNU実装には代替オプションがgrep
あります-H
。
find . -name '*.py' -exec grep -l something {} +
少なくとも1つの一致する行を持つファイルのファイル名のみを印刷します。
ファイル名の印刷今後行を一致させるには、代わりにawkを使用できます。
find . -name '*.py' -exec awk '
FNR == 1 {filename_printed = 0}
/something/ {
if (!filename_printed) {
print FILENAME
filename_printed = 1
}
print
}' {} +
または、各ファイルに対して2回呼び出します。各ファイルに対して少なくとも1つのコマンドと最大2つのコマンドをgrep
実行し、ファイルの内容を2回読み取ると効率が低下します。grep
find . -name '*.py' -exec grep -l something {} \; \
-exec grep something {} \;
いずれにせよ、find
そのように出力を繰り返したくありません。そして変数を引用することを忘れないでください。
GNU ツールでシェルループを使用するには:
find . -name '*.py' -exec grep -l --null something {} + |
xargs -r0 sh -c '
for file do
printf "%s\n" "$file"
grep something < "$file"
done' sh
(FreeBSDおよびその派生物にも適用されます)。