複雑な検索でfindとgrepを組み合わせる方法は?(GNU / linux、find、grep)


17

GNU / Linuxで、類似のディレクトリ構造を共有しているが、同じディレクトリツリーではないいくつかのファイルでテキスト検索を実行しようとしています。

同じツリー構造(Code Igniter MVC PHPフレームワーク)を共有する多くのサイトを持つWebサーバーがあるため、各サイトのツリーの下の特定のディレクトリで検索したい、例:

/srv/www/*/htdocs/system/application/

ここで、*はサイト名です。そして、それらのアプリケーションディレクトリから、すべてのツリーをリーフまで検索し、内部にテキストパターンがある* .phpファイルを検索したいとします。たとえば、「debug(」、正規表現は不要です。

findgrepの使用方法は知っています、それらを組み合わせるのは苦手です。

どうすればいいですか?
前もって感謝します!

回答:


21

試して

find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep "debug (" {} \; -print

これによりapplication.php拡張子の付いたファイルが存在するフォルダーを再帰的に検索して、に渡す必要がありgrepます。

これを最適化するには、次を実行します。

find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep -H "debug ("

これは、単一のコマンドへの引数として出力されるxargsすべての.phpファイルを渡すために使用します。例えば、。のオプションとオプションは、ファイル名とディレクトリ名のスペースが正しく処理されるようにします。に渡されるオプションは、すべての状況でファイル名が印刷されることを保証します。(デフォルトでは、複数の引数が渡された場合にのみファイル名を出力します。)findgrepgrep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

man xargsから:

-0

      入力項目は空白ではなくヌル文字で終了し、引用符とバックスラッシュは特別ではありません(すべての文字が文字どおりに使用されます)。ファイルの終わり文字列を無効にします。これは他の引数と同様に扱われます。入力項目に空白、引用符、またはバックスラッシュが含まれる場合に役立ちます。GNU find -print0オプションは、このモードに適した入力を生成します。


1
+1。ただし、各phpファイルに対してgrepが実行されます。多数のファイルがある場合は、さらに最適化することができますfind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen

@jackem同意しました。それに応じて回答を更新します。
nagul

2
別の小さな改善:xargsはgrepにファイル名を1つだけ渡すことができます。この場合、grepは一致するファイル名を表示しません。grepコマンドに-Hを追加して、ファイル名を表示させることができます。
ランディオリソン

@Randyそれは非常に有効なポイントです。
nagul

3
これは真のネクロマンシーですが、実行するのと同じ種類の単一プロセス実行を実行する代わりにオペレーターを使用GNU findできます。したがって、この回答の例と同じことを行いますが、プロセスフォークが1つ少なくなります(ファイル名のトラブルのリスクは0になります)。+\;xargsfind /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +xargs
ダニエルアンダーソン

10

findこの例では不要です。grep直接使用できます(少なくともGNU grep):

grep -RH --include='*.php' "debug (" /srv/www/*/htdocs/system/application/

そして、私たちは単一のプロセスフォークになりました。

オプション:

  • -R, --dereference-recursive Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
  • -H, --with-filename Print the file name for each match. This is the default when there is more than one file to search.
  • --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude).
  • --exclude=GLOB Skip any command-line file with a name suffix that matches the pattern GLOB, using wildcard matching; a name suffix is either the whole name, or any suffix starting after a / and before a +non-/. When searching recursively, skip any subfile whose base name matches GLOB; the base name is the part after the last /. A pattern can use *, ?, and [...] as wildcards, and \ to quote a wildcard or backslash character literally.

好奇心だけのために、-RHオプションはどういう意味ですか?
ガス

@Gus:man grepオプションの説明の抜粋を投稿に追加しました。
ダニエルアンダーソン

0

シェルはphpファイルを見つけてgrepに渡すことができます。bashの場合:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.