如何搜索给定字符串的文件(其中一些可能是目录(在这种情况下是递归的))?
我想在源文件中搜索类定义,因此如果每个输出字符串之前都有包含文件的名称,那就太好了。
答案1
您可以使用 grep:
grep -rn 'classname' /path/to/source
这还将打印每个匹配项旁边的行号。
不区分大小写:
grep -rin 'classname' /path/to/source
在所有 cpp 文件中非递归搜索:
grep -n 'classname' /path/to/source/*.cpp
答案2
以上所有答案都可以很好地工作,但如果字符串不仅仅存在于源代码中,则可能会导致误报。假设您正在寻找 Java 项目中使用 FooBar 类的位置,您可以搜索所有名为 *.java 的文件并仅 grep 这些文件。
# grep "FooBar" -Hn $(find -name "*.java")
$() 之间的部分将扩展为该命令的输出。-H 打印出文件名。如果有多个文件名,这是默认设置,但我们在此处明确添加它,以防扩展仅返回一个文件名。-n 打印匹配的行号。
这对于小型项目来说很有用,但是如果你正在处理较大的项目,则 find 可能会扩展到比命令行限制更长的字符串。因此,使用以下方法更安全:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -Hn
xargs 将从标准输入中获取输入并将其拆分,以便适合命令行,必要时多次运行该命令。-print0 和 -0 是处理名称中带有空格的文件所必需的。
您还可以使用以下命令查找所有匹配的文件名:
# find -name "*.java" -print0 | xargs -0 grep "FooBar" -l
-l 将只显示文件名,一旦找到匹配项便停止在特定文件中查找。
如果您经常做这种事情,您可能需要查看 ctags 或 exuberant tags 等工具,它们维护源代码的搜索索引并可以快速回答这些问题。vim 和 emacs 都支持这些工具。您可能还想查看 eclipse 等 IDE,它可以很好地进行交叉引用。
(我知道您正在寻找一个类定义,但在 Java 中,类将在与该类同名的文件中定义。如果您正在执行 cpp,您可以执行以下操作:
# find -name "*.cpp" -o -name "*.cc" -o -name "*.h" -o -name "*.hpp" -print0 | \
xargs -0 egrep "class\s+FooBar" -Hn
答案3
通过搜索源代码,我发现 ack (betterthangrep.com),引用营销人员的话来说,比 grep 更好。它的输出更易于阅读,并且会自动执行很多操作,例如忽略非源代码文件:VCS 目录(例如 CVS 和 .svn)、备份文件。
答案4
grep -r string *
在当前目录和所有子目录中的所有(非隐藏)文件中递归查找包含字符“string”的所有文件。您可以使用常用的正则表达式来调整字符串。有关更多选项,请参阅 grep info/man 页。