複数のファイルで最初の一致を見つける方法

複数のファイルで最初の一致を見つける方法

findコマンドに文字列またはパターンの最初の出現または出現を検索させる方法はありますか?それぞれ内複数のファイルがありますか?私は一般的な構文を使用しました。

 find dir -iname '*.ext' -exec command 'pattern' {} \;

(私は偶然にPDFを検索していますが、-exec pdfgrepこれは一般的な質問の特別なケースなので、後でまたは別々に扱うことができると仮定します。)

-quitこれは、最初の結果を生成するためにfindとorを使用して検索する一般的な問題とは異なることに注意してくださいhead -n 1

答え1

(例では)一度一致した後にファイルの読み取りを停止するには、-mGNUオプションを使用してください。grep

find dir -iname '*.ext' -exec grep -m 1  'pattern' {} \;

答え2

awkスクリプトを使用してこれを実行できます。

find dir -iname '*.ext' -exec awk '/pattern/{print;exit}' {} \;

答え3

最初の一致後に検索コマンドが停止しない場合は、結果をフィルタリングして最初の出力ラインのみを維持できますcommand 'pattern' /path/to/file | head -n 1。コマンドは終了時にSIGPIPEシグナルを受信するため、バッファheadリングのためにより多くの一致が見つかる可能性がありますが、一致が多い場合はファイルが終了する前に停止します。

(パイプを設定するには)シェルコマンドを実行する必要があるため、shから呼び出す必要がありますfind。引用符に注意してください。シェルには引用符レイヤーが必要で、で始まるシェルには引用符レイヤーが必要ですfind。内部シェルコマンドの周りに一重引用符を入れて、ハックを使用して一重引用符内で作業できます'\''(一重引用符リテラルの終了、\'リテラルの一重引用符、同時に新しい二重引用符リテラルの開始)。パターンに他のものは必要ありません(パターンに'aで表されるaが含まれていない'\''場合はこれを行う必要があります'\'\\\'\'')。

find dir -iname '*.ext' -exec sh -c 'command '\''pattern'\'' "$0" | head -n 1' {} \;

パターンを引用することを心配することなく、外部に配置してパラメータとして渡すことができます。

find dir -iname '*.ext' -exec sh -c 'command "$0" "$1" | head -n 1' 'pattern' {} \;

シェルを呼び出してファイルを繰り返す方が少し高速です。

find dir -iname '*.ext' -exec sh -c '
    for f; do command "$0" "$f" | head -n 1; done
' 'pattern' {} +

関連情報