在 GNU/Linux 中,我尝试对一些具有相似目录结构但不在同一目录树中的文件进行文本搜索。
我有一个 Web 服务器,其中有许多站点共享相同的树结构(Code Igniter MVC PHP 框架),因此我想在树中的特定目录中搜索每个站点,例如:
/srv/www/*/htdocs/system/application/
其中 * 是网站名称。从这些应用目录,我想要搜索整个树直至它的叶子,以查找包含一些文本模式的 *.php 文件,比如说“debug(”,不需要正则表达式。
我知道如何使用寻找和grep但我并不擅长将它们结合起来。
我该怎么做?
提前致谢!
答案1
尝试
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
-print0
find
-0
xargs
-H
grep
grep
来自 man xargs:
-0
输入项以空字符而不是空格结尾,引号和反斜杠不是特殊字符(每个字符都按字面意思理解)。禁用文件结尾字符串,该字符串将像其他任何参数一样处理。当输入项可能包含空格、引号或反斜杠时很有用。GNU find 选项
-print0
会生成适合此模式的输入。
答案2
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.
答案3
您的 shell 可以找到 php 文件并将其提供给 grep。在 bash 中:
shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php