【问题标题】:show filename with matching word from grep only仅显示来自 grep 的匹配单词的文件名
【发布时间】:2020-05-27 16:49:48
【问题描述】:

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

'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)。

感谢您的帮助

【问题讨论】:

  • GNU grep 的选项-H 可能会有所帮助。
  • 酷,谢谢!!这已经非常接近答案了(我还没有意识到,但确实很有帮助)

标签: grep find match ksh


【解决方案1】:

您可以将几个选项传递给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

【讨论】:

  • 完美,就是这样,谢谢!! (ps 额外问题 - 如何在返回值中包含文件名而不使用我使用的尴尬循环?)
【解决方案2】:

从您的示例看来,所有文件都在一个目录中。因此,以下工作立即生效:

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 报告匹配的文件名

【讨论】:

  • 嗨@monok,谢谢,但请参阅已接受的答案 - 问题不是 grepping,而是找到完整的单词
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-05
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-14
相关资源
最近更新 更多