如何结合 find 和 grep 进行复杂的搜索?( GNU/linux, 查找, grep )

Pet*_*uza 20 linux grep gnu command-line find

我试图在一些共享类似目录结构但不在同一目录树中的文件中进行文本搜索,在 GNU/Linux 中。

我有一个 Web 服务器,其中有许多站点共享相同的树结构(Code Igniter MVC PHP 框架),所以我想在树下的特定目录中搜​​索每个站点,例如:

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

其中 * 是站点名称。从这些应用程序目录中,我想搜索所有树直到它的叶子,寻找一个 *.php 文件,里面有一些文本模式,假设“调试(”,不需要正则表达式。

我知道如何使用findgrep但我不擅长将它们结合起来。

我该怎么做?
提前致谢!

小智 24

尝试

find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep "debug (" {} \; -print
Run Code Online (Sandbox Code Playgroud)

这应该递归搜索下面的文件夹以application查找具有.php扩展名的文件并将它们传递给grep.

对此的优化是执行:

find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep -H "debug ("
Run Code Online (Sandbox Code Playgroud)

这用于xargs将所有.php文件输出find作为参数传递给单个grep命令;例如,。该的选择和的选项确保文件和目录名的空间得到正确处理。传递给的选项确保在所有情况下都打印文件名。(默认情况下,仅在传入多个参数时才打印文件名。)grep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

来自 man xargs:

-0

      输入项由空字符而不是空格终止,引号和反斜杠并不特殊(每个字符都按字面意思表示)。禁用文件字符串的结尾,它被视为任何其他参数。当输入项可能包含空格、引号或反斜杠时很有用。GNU find-print0选项生成适合此模式的输入。

  • 这是真正的死灵术,但是 `GNU find` 可以使用 `+` 操作符代替 `\;` 来执行与 `xargs` 相同的单进程执行。因此,`find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +` 与此答案中的 `xargs` 示例执行相同的操作,但少了一个进程分支(文件名问题的风险仍然为 0)。 (3认同)
  • 另一个小改进:xargs 可能只将一个文件名传递给 grep,在这种情况下,如果匹配,grep 将不会显示文件名。您可能希望将 -H 添加到 grep 命令以强制它显示文件名。 (2认同)

Dan*_*son 11

find这个例子甚至不需要,可以grep直接使用(至少GNU grep):

grep -RH --include='*.php' "debug (" /srv/www/*/htdocs/system/application/
Run Code Online (Sandbox Code Playgroud)

我们归结为一个单一的进程分支。

选项:

  • -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.