xargs便利、空白対策もばっちり!!

あるディレクトリ以下の、.cppを拡張子に持つファイルからpragmaという文字列の入ったファイルをリストアップする際に使うコマンドは、

>grep pragma *.cpp

ですが、再帰的に検索する際に-rオプションを付けても上手く動きません。
今までは仕方なしに-rオプションと、grep結果にさらにgrepをかける

>grep -r pragma . | grep '.cpp'

を使っていたのですが、これだと.cppが文字列に入っている場合もリストアップしてしまうのですよね。なんだか気持ちが悪いし、なにより効率が悪いですよね。
で、最近見つけたのがfindとxargsの組み合わせです。以下のようにタイプすることで、findによりファイル名が.cppのファイルに対してgrepをかけてくれるようになりました。

>find . -name '*.cpp' | xargs grep pragma

ただ、この方法にも問題はあって、xargsの動作仕様として

xargs はまず標準入力から空白または改行で区切られた文字列群を読み込む

てのがあるとおり、findが空白付きファイル名を出力してしまうと、空白で引数を分割してしまうという問題が発生するようです。で、「xargs 空白」をキーワードにwebを漁っていたら問題は即解決、

  • findに-print0オプションを付ける(出力ファイル名の間にヌル文字を挟んでくれるようです)
  • xargsに-0オプションを付ける(空白や改行でなく、ヌル文字で区切られた文字列を一つの引数とみなしてくれるようです)

という方法で、上手く対処できました。めでたしめでたし。コマンドラインは以下のようになります。

>find . -name '*.cpp' -print0 | xargs -0 grep pragma

参考リンク google:xargs 空白