約500個の文字列があり、それらを含むファイルをディレクトリ内で検索して、文字列を含むファイル名を取得します。これまでのところ、私は使用しています:
find -name 'LYFNRE.*' -exec grep -f file1.txt {} \; -print
しかし問題は、文字列が多くのファイルで見つかる可能性があるため、膨大な出力のために、どの文字列が存在し、どの文字列が欠落しているかを見つけるのが難しいことです。文字列が見つかった場所の対応するファイル名で文字列を印刷するのを手伝ってくれませんか。
grep
にファイル名を渡させるだけです。 GNU grep
はこれを行うことができます:
grep -HFf ../strings.txt *
次のような出力が表示されます。
[filename]:[matched_line]
...ディレクトリ内のすべてのファイルのすべての一致について。行番号も取得できます。
grep -HnFf ../strings.txt *
...提供する...
[filename]:[line_number]:[matched_line]
問題は、一度に1つのファイルをgrep
に渡すことです。 grep
がコマンドラインで単一のファイルを見つけた場合、検索する場所が正確にわかっていると想定しているため、一致の前にファイル名は表示されません。
grep
が常にファイル名を出力するように強制するコツは、/dev/null
も渡すことです(一致するものはありません)。一部のgrep実装には、そのためのオプションがあります:-H
。
さらに、-exec … {} +
の代わりに-exec … {} \;
を使用して、一度に多くのファイルに対してプログラムを実行できます。これはより高速です。 /dev/null
または-H
を渡す必要があります。一致するファイルが1つあるため、またはgrep
が数回呼び出され、1回は単一のファイルに関係しています。
find -name 'LYFNRE.*' -exec grep -f file1.txt /dev/null {} +
GNU grepおよび最近のBSD実装(OSXを含む)は、grep
を必要とせずにfind
を再帰的に呼び出すオプションをサポートしています。
grep -R --include='LYFNRE.*' -f file1.txt -H .
または、シェルで再帰的グロビングを行うこともできます。 zshでは、これはそのまま使用できます。 bashでは、最初にshopt -s globstar
を実行する必要があります。また、bashがディレクトリへのシンボリックリンクを介して再帰することに注意してください(find
やzshとは異なります)。
grep -f file1.txt /dev/null **/LYFNRE.*
egrepを使用:
egrep -n "str1|str2|str3" file_names
-nは、文字列が見つかった特定のファイルの行番号を出力します