複数ファイルの中から特定の文字列を検索したいときに使えるLinuxとMac用のコマンドを紹介します。
jQueryを呼び出しているページの一覧出せる?みたいな要望を一瞬で叶えてくれる素敵なコマンドたちです。
覚えやすい方のコマンドと、細かい調整のできるコマンドの2種類があるので、用途に合わせて使い分けてください!
Contents
grep r を使う方法
指定のファイルに指定の文字列が含まれているかを調べる grep コマンドにある r オプションを使う方法です。
下記のコマンドで、カレントディレクトリ以下にある全ファイルの中に xxx という文字列があるファイル名とその行の文字列を画面上に出力してくれます。
grep -r xxx .
./abc.txt:xxx
./abc.txt: xyz xxx
./xxx/abc.txt:xxx
コマンドの説明
grep
指定のファイルに指定の文字列が含まれているかを調べるコマンドです。
-r
grep コマンドのオプションです。recursive の略で、r でも R でも問題ありません。
ファイル名のみの表示にする場合は、l オプションを追加して、rl とします。
grep -rl xxxxx .
./abc.txt
./xxx/abc.txt
この l オプションと sed コマンドを組み合わせると一括置換も可能です。
xxxxx
この部分が検索したい文字列の場所です。
スペースを含む文字を検索したい場合、シングルクォート(’ ‘)で囲んでください。
grep -r 'foo bar' .
. (ドット)
検索先のディレクトリのパスです。「 . 」はカレントディレクトリになります。
相対パス、絶対パスのどちらでも大丈夫です。
*.php のように拡張子を指定する部分一致のような検索も可能ですが、再起検索できなくなってしまうので、後で紹介する include オプションを使いましょう。
grep r の複雑な使い方
r と l のオプション以外にも、複数ファイルの一括検索のために覚えておくと役に立つ grep のオプションを紹介します。grep には、他にも便利なオプションがたくさんありますが、本題から逸れてしまうので、今回は複数ファイルの一括検索という状況で使うオプションに限定して紹介いたします。
先にオプションをたくさん使ったバージョンを載せておきます。
grep -rniE '(foo|bar)' --include='*.php' /home/user/xxx/
-i オプション
大文字・小文字の違いを無視して検索します。
-n オプション
検索結果に行番号を表示します。
-e, -E, -P オプション
正規表現による検索ができます。
–include=’*.php’ オプション
ファイル名のパターンを指定できます。複数指定することで、複数のファイル名のパターンを指定可能です。
-L オプション
指定文字列が含まれないファイルを表示します。
-h オプション
検索結果にファイル名を載せないためのオプションです。
find xargs grep を使う方法
複数ファイルでの検索といえば、こちらの方が有名かもしれません。
簡単な検索であれば grep のみで検索できるのですが、find を使う方法では、24時間以内に更新したファイルの中で・・・といった複雑なファイル指定が可能になります。
最短では以下のコマンドでカレントディレクトリ配下にあるファイルを検索することができます。
find . | xargs grep {調べたい文字}
環境によっては、「 . 」の省略すら可能です。
コマンドの説明
find
指定したディレクトリ以下のファイルを検索します。
検索先のパスの指定が必須の環境と、カレントディレクトリの場合は省略可能な環境があります。
それ以外は全てオプションになります。
. (ドット)
検索先のディレクトリのパスです。「 . 」はカレントディレクトリになります。
相対パス、絶対パスのどちらでも大丈夫です。
*.php のように拡張子を指定する部分一致のような検索も可能ですが、再起検索できなくなってしまうので、後で紹介する name、iname オプションを使いましょう。
| (パイプ)
前のコマンドの実行結果を後ろのコマンドに受け渡しるすためのコードです。
xargs
標準入力の文字列を次のコマンドの引数に渡して実行します。
grep
指定のファイルに指定の文字列が含まれているかを調べるコマンドです。
find xargs grep の複雑な使い方
もう少し複雑な使い方もできます。長くなりますが、find 関数の機能をフル活用すればピンポイントで必要なファイルを調べることも可能です。
find . -type f -mtime -1 -iname '*.php' -print0 | xargs -0 grep -IrniE '(foo|bar)'
-type f
ファイル種別の指定で、ファイルを指定しています。
iname、name
大文字小文字を区別する場合は name、大文字小文字を区別しない場合は iname を利用します。
-print0、xargs -0
空白文字を含むパスやファイル名がある場合、このオプションが必要になります。
mtime、atime、ctime、mmin、amin、cmin
最終アクセスや最終更新から一定の時間内のファイルを対象にするオプションです。
○time は指定の数字x24時間、○minは指定の時間x分になります。
-I オプション
バイナリファイルを無視するオプションです。
他の複数ファイルから検索する方法
下記のような find exec を使う方法でも検索可能ですが、検索で見つかったファイルの数だけ grep が実行されるため、だいぶ遅いので非推奨です。
find . -name *\.php -exec grep {調べたい文字} {} \;
まとめ
基本的には、grep -r {検索したい文字列} {検索したい場所}で複数ファイルの中から任意の文字列を含むファイルとその場所を取得することができます。
ただ、特定の条件のファイルに限定したい場合など、find xargs grep の方のコマンドがあることを覚えておくと、対応の幅が広がります。
find コマンドと grep コマンドをもっと調べれば、このページで説明しているよりもはるかに複雑な検索をすることも可能です。