何百ものPHPファイルがあるサイトでクラス宣言を探しています。grepを使用して現在のフォルダーとサブフォルダーでこれを行うにはどうすればよいですか?
cd
フォルダーにing をテストしてから
grep -r 'class MyClass' *.php
何百ものPHPファイルがあるサイトでクラス宣言を探しています。grepを使用して現在のフォルダーとサブフォルダーでこれを行うにはどうすればよいですか?
cd
フォルダーにing をテストしてから
grep -r 'class MyClass' *.php
回答:
あなたが試すことができます
grep -r --include=*.php "search string" /path/to/dir
grepではなくctagsのようなものを使用することをお勧めします。ただし、必要に応じて、次のようなことができます
find <top level dir> -name \*.php | xargs grep "class MyClass"
もちろんこれは、あなたが間に1つだけのスペースがあることを前提とclass
し、myClass
真実ではないかもしれないが。ただし、正規表現を変更して任意の数の空白を探すのは簡単です。
を使用する場合-r
、おそらく現在のディレクトリだけを再帰的に検索する必要があります。
grep -r 'class MyClass' .
上記の最後の期間に注意してください。
あなたが言っgrep
たことは、すべての*.php
ファイルまたはディレクトリを再帰的に検索したいが、おそらく.php拡張子で終わるディレクトリを持っていなかったということです。上記は検索を行うための最も簡単な方法ですが、他の種類のファイルも含まれています。これは、どこにでも.svnディレクトリがある場合に特に問題となります。他のファイルタイプがあまりない場合は、一般に上記で十分であり、うまく機能します。
ほとんどのgrepの化身には、検索可能なファイル拡張子を指定する方法がないため、通常はfindと組み合わせて使用します。
find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} \;
-iname
grepの一部のバージョンに、大文字と小文字を区別しないファイル名検索を実行するように指示しますが、findの非GNUバリアントの多くはサポートしていないため、-name
代わりに使用できます。
上記の-exec
オプションには、すべてのファイルに対してgrepを呼び出すという副作用があり、かなりコストがかかります。
grepのさらに他のバージョンは、findに+
引数を一緒に追加して実行可能ファイルの呼び出し回数を減らすよう指示するa をサポートしています。
find <startDir> -iname '*.php' -exec grep 'class[ \t]*MyClass' {} + \;
呼び出しを減らすために頻繁に推奨される方法は、xrepを使用することです。これは、grepを可能な限り数回、ただし必要な回数だけ起動します。
find <startDir> -iname \*.php | xargs grep "class[ \t]*MyClass"
xargs
コマンドラインでサポートされる引数の最大数までgrepを渡すのに十分賢いですが、上記のバリエーションはスペースのような特定の文字をうまく処理しません。たとえば、ファイル名grepが引数として「the」を受け取り、引数として「file.php」を受け取る場合、「the file.php」の場合、両方は見つかりません。代わりに使用します:
find <startDir> -iname \*.php -print0 | xargs -0 grep "class[ \t]*MyClass"
print0
そして、-0
一緒に作業し、使用の引数は、引数が完全かつ明確に識別されるようにヌル文字が続きます。
class
、またはタブの後に複数のスペースがある場合、正規表現を変更してより多くの文字を許可することができます。class[ \t]*MyClass
StackOverflowのこの投稿には他の例があり、.svnディレクトリなどの特定のディレクトリを除外する方法を示しています。
おそらく、大文字と小文字を区別せず、空白の許容範囲が必要です。現在のディレクトリで目的のファイルパターンのインスタンスが見つからない場合、grepは終了します。どこから始めればよいかを知る必要があり、一致するファイルがなければ開始パスは生成されません。
目的の拡張子のファイルが少なくとも1つある場合は、egrep -irを使用できます。 find
またxargs
、grepが失敗する単一のフラット(ただし非常に大きな)ディレクトリと追加の修飾子(たとえば、.inc、.php、およびphp3ファイルのみを検索する場合)で威力を発揮します。しかし、それは私の経験ではかなりの利便性と速度を失います。人間が作成したクラス宣言の場合、大きな問題は空白になります。したがって、grepの代わりにegrepを使用します。また、速度を上げるためLC_ALL = C。便宜上、私はよく使用します:
LC_ALL=C egrep -irn "class[ ]*myclass([ ]|\n)" * | egrep "\.(inc|php[35]?)"
-i -- case insensitive
-r -- recursive for all file pattern (here *)
-n -- include the line number
LC_ALL=C -- search in ASCII, not in utf8, this is much faster.
[ ]* -- match any number of spaces before the class name
([ ]|\n) -- match a space or newline after the classname
これは、などのコメントと一致する// class myclass exists in file
場合がありますが、それらは比較的小さいことがわかります。... | fgrep -v '//'
次のように、egrepファイルパターンに、より複雑なファイルマスクを含めることができます(たとえば、ほとんどの.incおよび.phpファイルをキャッチするため)。
egrep "pattern" *.[ip]*
これは(最初のオプションで)非常に高速で、ほとんどがphpファイルに制限されます。
HTH
grep -r
与えたくないものについて何か言いたいかもしれません。