find を grep にパイプするときに、grep の一致の強調表示を保持するにはどうすればよいですか?

find を grep にパイプするときに、grep の一致の強調表示を保持するにはどうすればよいですか?

を実行するとgrep foo bar.txt、grep は 内の "foo" の各出現箇所を強調表示しますbar.txt。しかし、grep が検索するファイルを判別するために を使用したい場合もありますfind。その場合は、次のようにします。

find . -iname "*.abc" | xargs grep foo

あるいはこれ:

find . -iname "*.abc" -exec grep foo {} \;

どちらの場合も、grep は指定されたファイル内の「foo」の出現を正しく検出しますが、出力にはまったく強調表示されません。

findハイライト表示を失わずに、grep で検索するファイルを選択し続けるにはどうすればよいですか?

私は Ubuntu 12.04 上で Gnome Terminal 3.4.1.1 を実行しており、シェルには bash を使用しています。

答え1

どちらのコマンドでも、問題は、grepではなく別のコマンドが実際の出力 (それぞれ と ) を生成するxargsことですfind

grep各ファイル名を直接呼び出すことでこれを解決できます。

IFS=$'\n'
for FILE in $(find . -iname "*.abc"); do
    grep foo $FILE
done
unset IFS

あるいはワンライナーとして:

IFS=$'\n';for FILE in $(find . -iname "*.abc");do grep foo $FILE;done;unset IFS

使い方:

  • IFS=$'\n'内部フィールド区切り文字を改行文字に設定します (そうしないと、ファイル名にスペースがあると問題が発生します)。

  • for FILE in $(COMMAND); do COMMANDS doneで指定されたファイルをループしCOMMAND、変数をFILE現在のファイルに設定して を実行しますCOMMANDS

  • grep foo $FILEを検索しfoo$FILE結果を送信する直接スクリーンに。

  • unset IFS内部フィールドセパレーターをデフォルト値に戻します (スクリプトでは必要ありません)。

答え2

grep出力を再度実行して色を付けるだけです。

ここでも似たようなことをしました:grepから一致した箇所の周辺データを取得する

関連情報