仅显示来自 grep 的匹配词的文件名

show filename with matching word from grep only

我正在尝试查找日志文件中发生的单词,并显示与以下模式匹配的任何内容的日志文件名:

'BA10\|BA20\|BA21\|BA30\|BA31\|BA00'  

因此,如果文件 dummylogfile.log 包含 BA10002,我希望获得如下结果:

dummylogfile.log:BA10002

如果日志文件出现两次重复匹配则完全没问题。

我得到的最接近的是:

for f in $(find . -name '*.err' -exec grep -l 'BA10\|BA20\|BA21\|BA30\|BA31\|BA00' {} \+);do printf $f;printf ':';grep -o  'BA10\|BA20\|BA21\|BA30\|BA31\|BA00' $f;done

但这给出了类似的东西:

./register-05-14-11-53-59_24154.err:BA10
BA10
./register_mdw_files_2020-05-14-11-54-32_24429.err:BA10
BA10
./process_tables.2020-05-18-11-18-09_11428.err:BA30
./status_load_2020-05-18-11-35-31_9185.err:BA30

所以,
1)只有第二个匹配项和
有空行 2) 未显示完整匹配项(例如 BA10004)。

感谢您的帮助

从你的示例来看,所有文件似乎都在一个目录中。所以下面的工作马上:

grep -l 'BA10\|BA20\|BA21\|BA30\|BA31\|BA00' *.err

如果文件在不同的目录中:

find . -name '*.err' -print | xargs -I {} grep 'BA10\|BA20\|BA21\|BA30\|BA31\|BA00' {} /dev/null

解释:将/dev/null添加到文件名{}中强制grep报告匹配的文件名

您可以将几个选项传递给 grep:

  • -H: 这将报告文件名和匹配项
  • -o: 只显示匹配项,不显示整行
  • -w: 匹配项必须代表一个完整的单词(从 [A-Za-z0-9_] 构建的字符串)

如果我们查看您的正则表达式,您使用 BA01,这将仅匹配 BA01,它可以出现在文本中的任何位置,也可以出现在单词中间。如果你想让正则表达式匹配一个完整的单词,它应该读作 BA01[[:alnum:]_]*,它添加任何单词组成字符的序列(相当于 [A-Za-z0-9_])。您可以使用

进行测试
$ echo "foo BA01234 barBA012" | grep -Ho "BA01"
(standard input):BA01
(standard input):BA01
$ echo "foo BA01234 barBA012" | grep -How "BA01" 
$ echo "foo BA01234 barBA012" | grep -How "BA01[[:alnum:]_]*" 
(standard input):BA01234

所以你的grep应该看起来像

grep -How "\('BA10\|BA20\|BA21\|BA30\|BA31\|BA00'\)[[:alnum:]_]*" *.err