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


17

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

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

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

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

我知道如何使用findgrep,但是我不擅长将它们组合在一起。

我该怎么做?
提前致谢!

Answers:


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文件输出find作为参数传递给单个grep命令。例如。确保正确处理文件名和目录名中的空格的选项和选项。传递给的选项可确保在所有情况下都打印文件名。(默认情况下,仅在传入多个参数时才打印文件名。)grep "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 2009年

@jackem同意。我将相应地更新答案。
nagul

2
另一个小改进:xargs可能只将一个文件名传递给grep,在这种情况下,如果存在匹配项,grep将不会显示文件名。您可能需要在grep命令中添加-H以强制其显示文件名。
兰迪·奥里森

@兰迪这是一个非常正确的观点。
nagul

3
这是真正的巫术,但GNU find可以让+操作员代替\;执行相同的单进程执行xargs。因此,find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +xargs该答案中的示例相同,但进程分叉少了一个(文件名出现问题的风险仍然为0)。
丹尼尔·安德森

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

@Gus:man grep在帖子中添加了选项描述的摘录。
丹尼尔·安德森

0

您的外壳程序可以找到php文件,并将其提供给grep。在bash中:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.