私はこれを大量に使用し、私が達成しようとする改善は、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およびその派生物にも適用されます)。
答え2
出力にファイル名を含めるようにgrepに指示できます。したがって、一致するものがあればコンソールに表示されます。ファイルに一致するエントリがない場合、ファイルの行は印刷されません。
find . -name "*.py" | xargs grep -n -H something
からman grep
:
-H Always print filename headers with output lines
-n, --line-number
Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed.
This option is ignored if -c, -L, -l, or -q is specified.
ファイル名にスペースを含めることができる場合は、NUL文字を区切り文字として使用するようにパイプを切り替える必要があります。これで、完全なコマンドは次のようになります。
find . -name "*.py" -print0 | xargs -0 grep -n -H something
答え3
GNU grepを使用している場合は、その-r
オプション--recursive
を使用して次の簡単な検索を実行できます。
grep -r --include '*.py' -le "$regexp" ./ # for filenames only
grep -r --include '*.py' -He "$regexp" ./ # for filenames on each match
find
より高度な述部が必要な場合にのみ必要です。
答え4
引数を使用してください-l
。
for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done
もっと興味深い使い方は次のとおりです。
for file in $(find . -name '*.py' -exec grep -l something '{}' +); do echo "$file"; grep something $file; done