追記
以下と思っきしかぶってます。こっちがむしろ小さくまとまっていてきれいです。
あと、上記のコメント欄の-exec grep {} +
が少し気になりますので、分かったらまた別の記事に。
こんなときに使える
ack
とかag
がなく、git
のレポジトリ以下でもないところで、特定の文字列を含むファイルを列挙したい。
また、できればその行を表示したい。
やり方
オススメではないが、一応できる。
$ for f in {foo,bar,baz}.c; do echo hogehoge > $f; done
$ find . -type f -name '*.c' -exec grep hogehoge {} \;
hogehoge
hogehoge
hogehoge
- ファイル1個マッチするごとに
grep
が実行されるので、ファイルがたくさんあるときに面倒。 -
-exec
のルールがめんどい。{}
にファイル名、\;
でコマンドの終わりを指定するが、空白を\
の前に入れたり、bashがfind
コマンドそのものの終わりと勘違いしないように;
の前に\
を入れなきゃいけなかったりする。あと、文字列がマッチしたファイル名を出してくれない。
オススメしたいやりかた
$ for f in {foo,bar,baz}.c; do echo hogehoge > $f; done
$ find . -type f -name '*.c' | xargs grep hogehoge
./baz.c:hogehoge
./foo.c:hogehoge
./bar.c:hogehoge
ただし、ファイル名に空白を含むファイルをfind
が吐いたときに問題になる。
そういうファイルがなければ、上記で十分
$ for f in {foo,bar,baz}.c; do echo hogehoge > $f; done
$ echo hogehoge > hoge\ poo.c
$ find . -type f -name '*.c' | xargs grep hogehoge
./baz.c:hogehoge
./foo.c:hogehoge
./bar.c:hogehoge
grep: ./hoge: No such file or directory
grep: poo.c: No such file or directory
更におすすめしたいやり方
$ for f in {foo,bar,baz}.c; do echo hogehoge > $f; done
$ echo hogehoge > hoge\ poo.c
$ find . -type f -name '*.c' -print0 | xargs -0 grep hogehoge
./baz.c:hogehoge
./foo.c:hogehoge
./bar.c:hogehoge
./hoge poo.c:hogehoge
結論
プアな環境下で特定の文字列を含むファイルを列挙したければ、とりあえず
find . -type f -name 'ファイル名' -print0 | xargs -0 grep 文字列
でやれば大体オッケー。
めんどかったら、find . -type f -name 'ファイル名' | xargs grep 文字列
でやって、エラーが出たら前述のやつをやるのもあり。