我有大约 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/null
or -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 将打印找到字符串的特定文件中的行号