如何循环遍历当前目录和子目录中的所有文件来查找字符串?

如何循环遍历当前目录和子目录中的所有文件来查找字符串?

您好,例如,我试图循环遍历目录及其所有子目录以在所有文件中查找字符串“foo”。然后我想显示包含它的所有文件的文件名(包括完整路径)。

操作系统是unix并使用bash shell。

任何建议,将不胜感激。谢谢

答案1

您可以使用递归grepgrep至少在 GNU 中,这是一个-R选项:

grep -R foo /path/to/parent/directory

例如,如果您使用完整路径(如上所示),/home/callsign223/foo/则所有文件都将显示其限定路径。如果您只想查看文件名而不是匹配的行,则可以使用-l仅打印文件名:

grep -lR foo /path/to/parent/directory

请注意,该选项不可移植,并且并非所有实现-R都支持。grep

答案2

如果grep -R不是一个选项,那么您可以使用在每个文件上find运行:grep

find ./ -type f -exec grep -Hni "some-string" {} ';'

答案3

适用于所有当前 Unix 系统的方法是使用find查找文件,然后grep识别包含字符串 的文件foo

find . -type f -exec grep -l -F -e 'foo' {} +

上面的命令将查找当前目录中或当前目录下的所有常规文件。对于批量找到的文件,grep将调用 来定位字符串foo。在文件中查找字符串时,grep立即输出文件的路径名并继续下一个文件,而不进一步读取当前文件。

  • 我们用来-l停止grep并在与给定模式匹配的第一行报告文件名。这可以通过忽略第一次命中后的文件位来加快处理速度。
  • 我们通常-Fgrep模式视为字符串而不是正则表达式。这可能会通过不尝试去正则表达式匹配来加快处理速度,并允许我们匹配看起来像正则表达式的字符串。
  • 我们使用-e给定的模式,以防万一它以破折号开头。在这种情况下,它不会这样做,但用foo变量替换该静态字符串会引入与以破折号开头的模式匹配的可能性,因此,这会被误认为是命令行选项。

不过,文件名列表通常没什么好处。您可能想要对这些文件执行某些操作。如果是这样,您可以将其作为find通过以下方式执行的实用程序的一部分来执行-exec

find . -type f -exec sh -c '
    for pathname do
        grep -q -F -e "foo" "$pathname" || continue
        # Do something with "$pathname" here
    done' sh {} +

这里我们调用一个简短的内联脚本来批量处理找到的文件。我们单独检查每个文件中的字符串foo,并忽略不包含该字符串的文件。我在内联脚本中添加了注释,您将处理"$pathname".

您还可以在调用内联脚本之前单独find执行上面的代码:grep

find . -type f -exec grep -q -F -e 'foo' {} \; -exec sh -c '
    for pathname do
        # Do something with "$pathname" here
    done' sh {} +

请注意第一个如何在调用通过该测试的文件-exec之前对当前文件进行测试。sh -c

答案4

我相信该ack实用程序将完全满足您的需求。它可能已经安装在您的系统上。如果没有的话可以从以下网址下载https://beyondgrep.com/

的一个很好的功能ack是它默认忽略二进制文件,并且可以给定命令行选项来限制通过某些指定的过滤器或文件类型搜索的文件类型(例如通过编程语言:将--type=cc搜索.c,,文件,将搜索第一行中匹配的任何文件)。用户还可以在命令行上或更永久地在文件中扩展这些类型。.h.xs--type=awk/awk/~/.ackrc

相关内容