自分の求めるパターンのファイルに対して grep を実行するためには grep と find を組み合わせます。
たとえば、特定のディレクトリ以下にあるすべての *.html ファイルに対して grep による検索をかけたいとして、次のようにコマンドを打ったとします。
grep -nir keyword *.html
grep で再帰検索をするために -r オプションをつけている点に注目してください。一見、これで目的は達成できそうな気がするのですが、実は高い確率でうまくいきません。なぜ、うまくいかないのかというと、実は grep コマンドは再帰的に潜るディレクトリを *.html というパターンによって振り分けてしまうのです。
つまり、次のような結果になります。
./image.gif # 検索されません、 *.html にマッチしません ./index.html # 検索されます ./sample.html # 検索されます ./samples.html/sample00.html # 検索されます ./samples.html/sample01.html # 検索されます ./samples.html/sample02.html # 検索されます ./samples.html/sample03.html # 検索されます ./files/file00.html # 検索されません、 files が *.html にマッチしません ./files/file01.html # 検索されません、 files が *.html にマッチしません ./files/file02.html # 検索されません、 files が *.html にマッチしません ./files/file03.html # 検索されません、 files が *.html にマッチしません
わかりますでしょうか?つまり、 grep は入るディレクトリを判定する際にも *.html で考えてしまうのです。これは多くの場合、意図する結果ではないはずです。
では、単純に grep -nir keyword * とすれば問題はないのでしょうか?たしかにそれもひとつの答えです。ですが、もし、検索対象のファイル数が膨大な場合は処理時間がかかります。以前のエントリーでも述べましたが Windows の場合は検索が終わるまで処理が返りません。
こういった場合、実は find コマンドを併用することで解決することが多くあります。
find コマンドは特定のディレクトリ以下にあるファイルをすべてリストアップするコマンドですが、これを grep コマンドに連結するとすっきりと目的を達成することができるようになります。
grep -nir keyword `find ./ -name '*.html'`
grep コマンドに本来パターンを指定する部分が `find ./ -name ‘*.html’` となっている点に注目してください。このようにバッククォートでコマンドを囲うと、その結果を外側のプログラムに渡すことができるのです。これが最近のエントリーで語っているコマンドの組み合わせなのです。
ただし、このバッククォートが使えるのは UNIX や Linux に採用されている bash などの高機能シェルでのみです。 Windows の場合は Cygwin をインストールすることで使うことができるようになります。
Contributions