私はfind
を使用しており、grep
でやりたいファイルのリストを取得しています。そのリストをgrep
にパイプするにはどうすればよいですか?
まあ、stdoutに書き込むコマンドで機能する一般的なケースは、xargs
を使用することです。これにより、コマンドの最後にコマンドライン引数をいくつでも追加できます。
_$ find … | xargs grep 'search'
_
または、コマンドをgrep
行にバッククォートまたは$()
で埋め込むと、コマンドが実行され、その出力が置き換えられます。
_$ grep 'search' $(find …)
_
これらのコマンドは、ファイル名に空白またはその他の特定の「奇妙な文字」(xargsの場合は_\'"
_、$(find …)
の場合は_\[*?
_)が含まれている場合は機能しません。
ただし、find
の特定のケースでは、指定された引数でプログラムを実行する機能が組み込まれています。
_$ find … -exec grep 'search' {} \;
_
_-exec
_と_;
_の間のすべてが実行するコマンドです。 _{}
_は、find
で見つかったファイル名に置き換えられます。これにより、ファイルごとに個別のgrep
が実行されます。 grep
は多くのファイル名を取得してそれらすべてを検索できるため、_;
_を_+
_に変更して、一致するすべてのファイル名をgrep
に一度に渡すように指示できます。
_$ find … -exec grep 'search' {} \+
_
grep
の一部のバージョン(非組み込みLinuxや [〜#〜] bsd [〜#〜] またはMac OS Xなど)には、再帰的な検索を行う-r
オプションがあります。 OpenBSDでは、-R
を使用します(以下の例のように--exclude
はありません)。これは、find
とgrep
の単純な組み合わせをカバーしています。
実装に-R
フラグがない場合、またはファイル照合基準をより洗練したい場合は、find
の-exec
プライマリを使用して、grep
を実行できます。いくつかの古いfind
実装は-exec
…+
をサポートしていません。これらのシステムでは、;
の代わりに+
を使用してください(これにより、ファイルごとに1回grep
が呼び出されるため、処理速度は遅くなりますが、それ以外の場合、結果は同じになります)。 /dev/null
トリックは、grep
が単一のファイルで呼び出された場合でもファイル名を表示することに注意してください(GNU grepおよびFreeBSD/NetBSD/OSX grepには、同じ効果を得るために-H
オプションがあります)。
find . -type f -name '*.o' -Prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .