在目录内的多个文件中搜索多个字符串,并打印找到的字符串和相应的文件名

在目录内的多个文件中搜索多个字符串,并打印找到的字符串和相应的文件名

我有大约 500 个字符串,我想在目录中搜索包含它们的文件并获取包含这些字符串的文件名。到目前为止我一直在使用:

find -name 'LYFNRE.*' -exec grep -f file1.txt {} \; -print

但问题是一个字符串可以在许多文件中找到,因此由于输出巨大,很难找到哪些字符串存在以及哪些字符串丢失。您能帮我打印字符串以及找到它们的相应文件名吗?

答案1

你应该只grep给你文件名。 GNUgrep可以做到这一点:

grep -HFf ../strings.txt *

这将为您提供如下输出:

[filename]:[matched_line]

...目录中每个文件的每个匹配项。您还可以获得行号:

grep -HnFf ../strings.txt *

...这提供了...

[filename]:[line_number]:[matched_line]

答案2

问题是您一次将一个文件传递到grep.当grep在命令行上看到单个文件时,它假设您确切知道要搜索的位置,因此它不会在匹配项前面显示文件名。

强制grep始终输出文件名的一个技巧是也通过/dev/null(永远不会有任何匹配)。一些 grep 实现有一个选项:-H

此外,您可以使用-exec … {} +而不是-exec … {} \;一次性执行多个文件的程序。这更快。您仍然应该传递/dev/nullor -H,因为可能会发生只对一个文件调用该命令的情况,要么是因为只有一个匹配文件,要么是因为有许多匹配项需要grep多次调用,而其中一次恰好涉及单个文件。

find -name 'LYFNRE.*' -exec grep -f file1.txt /dev/null {} +

GNU grep 和最近的 BSD 实现(包括 OSX)支持递归grep调用而不需要find.

grep -R --include='LYFNRE.*' -f file1.txt -H .

或者,您可以在 shell 中执行递归通配符。在 zsh 中,这是开箱即用的。在 bash 中,您需要shopt -s globstar先运行,并注意 bash 通过目录的符号链接进行递归(与find或 zsh 不同)。

grep -f file1.txt /dev/null **/LYFNRE.*

答案3

使用egrep:

egrep -n "str1|str2|str3" file_names

-n 将打印找到字符串的特定文件中的行号

相关内容