grep 拡張子、サブディレクトリ

備忘録
03 /03 2016
サブディレクトリ内を再帰的に、特定の拡張子のファイルだけgrep検索したい。
この手順がなかなか覚えられないので、備忘録として書いておく。

例:カレントディレクトリ以下の *.php を対象に hoge を探す場合
$ find ./ -name '*.php' | xargs grep 'hoge'
または
$ find ./ -name \*.php | xargs grep 'hoge'

※ *.php をそのまま書くと、シェル(bash等)がファイル名に展開してから find に渡す。
それは大きなお世話なので(多量にファイルがあるとシェルがエラーにしてしまう)
クォートで囲むか \ を付けることで、シェルによる展開を防ぐ。



正規表現を使うときは -G(基本正規表現)か -E(拡張正規表現)か -P(Perl正規表現) を付ける。
-G だと、[0-9]+ を [0-9]\+ と書く羽目になるので、-E がお薦め。
例:カレントディレクトリ以下の *.php を対象に $ret_ で始まる変数を探す場合
$ find ./ -name '*.php' | xargs grep -E '$ret_\w+'

非貪欲なマッチングをさせたいときは、-P を使う。
例:年月日時分秒が YYYY-MM-DD hh-mm-ss 形式の時、最初の - までを得る
$ echo '2016-01-23 23-45-59' | grep -o -P '^.+?-'
2016-

.+? がキモ。.+ だと貪欲なマッチングを行うので、最後の - までマッチする。
また -P を -E に変えるとやはり
2016-01-23 23-45-
にマッチしてしまうので、-E は非貪欲なマッチングに対応していないようだ。

※ -o は検索結果だけを返すオプション。



findの対象ディレクトリは複数指定できる。
例:lib/ か inc/ か site/ にある *.php を対象に test[0-9]+ を探す場合
$ find lib/ inc/ site/ -name '*.php' | xargs grep -E 'test[0-9]+'



検索パターンを複数指定するときは -or で繋ぐ。-o でも良い。
検索条件を \( \) で括る。
例: inc/ か tpl/ にある *.php か *.html を対象に input ... hidden を探す場合
$ find inc/ tpl/ \( -name \*.php -or -name \*.html \) |xargs grep -i -P 'input.+?hidden'

※ -i は大文字小文字を区別しないオプション。

Paq

忘れっぽい中年プログラマが、日々の開発作業の中で、忘れると困ることを書き留めています。