[Unix] 全てのサブディレクトリをgrep
grepの検索対象のファイルが一つのディレクトリにまとまっているのなら、
grep hoge *.c
で簡単に検索できるんですが、複数のディレクトリに分散している中から探すのに困ってしまいました。
複数ディレクトに分かれていても、ディレクトリの階層がすべて同レベルならば、
grep hoge */*.c
ってできるんですが、階層がまちまちの場合にはこれも使えない。
ということで、findコマンドとの合わせ技を教えてもらいました。
find . -name '*.c' | xargs grep hoge
あるいは、
find . -name '*.c' -exec grep hoge {} /dev/null \;
grepの引数に"/dev/null"が付いているのは、対象ファイルが1つの場合にもファイル名を表示させるため。
【追記】コメントでgrepのみでできる方法を教えて貰いました(fetaroさんありがとうございます)。
grepコマンドに-rというそのものズバリなオプションがありました。
grepの実装にもよるようですが(当時使わされてた環境にはなかったような?)。
grep -r --include=*.c hoge
xargsってコマンドは今回初めて知りましたが、標準入力を元に引数のリストを作成してコマンドを呼んでくれます。
findの-execだと、ファイル毎にgrepコマンドを発行してしまうので、xargsを使う方が速いようだ。
参考:
UNIXの部屋 検索: xargs
http://x68000.q-e-d.net/~68user/unix/pickup?xargs
Posted by froo at 18:34│
Comments(6)│
TrackBack(0)│
ツール
この記事へのトラックバックURL
http://trackback.blogsys.jp/livedoor/froo/50564541
環境によっては(zshだけ?)、ワイルドカードで「**」ってのが指定できて、ディレクトリを再帰的に展開してくれるらしい。AIXのkshじゃ使えなかったけど。
参考:
http://www-step.kugi.kyoto-u.ac.jp/~futaana/Briefcase/Zsh/wildcard.html
もっと簡単にコマンド展開で出来ますね。
grep hoge `find . -name '*.c'`
ただ、あんまりファイル数が多いとコマンドラインの文字数が制限値を超えてエラーになってしまうことがあるらしく、その場合はxargsでやらないとだめなようです。
findの-execでやると、grepに渡るファイルの数が1つだけになってしまうためにファイル名が出力されず、どこのファイルにあったのか分かりづらい。なので、必ずファイル名を表示してくれるようにダミーの"/dev/null"を渡すようにしました。
before:
find . -name '*.c' -exec grep hoge {} \;
after:
find . -name '*.c' -exec grep hoge {} /dev/null \;
サブフォルダーまで探せて、とても助かりました。
ありがとうございます!(^_^)
お使いのgrepのバージョンによりますが、
grepの-rオプションがあれば、再帰的に検索できますよ。
おお、ありがとうございます。
そうですよねありそうなもんですよね。
なんで当時は-rオプションが見つからなかったのだろうか。
AIXっていう特殊なOSだったからかな?