首页 > 解决方案 > BASH:在文件中搜索特定字符串并在匹配时读取与字符串关联的日志文件

问题描述

我有一个包含以下条目的文件

Command     : apply
Log File    : /u01/test/123.log

Command     : list
Log File    : /u01/test/456.log

Command     : rollback
Log File    : /u01/test/123.log

我的目标是查找应用/回滚命令,然后在日志文件中查找特定字符串“Make failed”正在查看 awk 范围模式,但感到困惑......请告知

标签: bashscripting

解决方案


我认为关键是使用多行记录处理而不是范围模式。

如果您有一个包含commands-and-logs.txt以下内容的文件(我将其添加/tmp/到您的示例内容中,以便我可以创建文件来测试它):

Command     : apply
Log File    : /tmp/u01/test/123.log

Command     : list
Log File    : /tmp/u01/test/456.log

Command     : rollback
Log File    : /tmp/u01/test/123.log

你可以运行:

awk -v RS="" -v FS="[:\n]" '$2 ~ /apply|rollback/ {print $4}' commands-and-logs.txt | sort -u | xargs grep -n "Make failed" /dev/null.

对我来说,/tmp/u01/test/123.log包含:

Line with Make failed 1
Line without...
Line without...
Line with Make failed 2
Line with Make failed 3
Line without...

/tmp/u01/test/456.log包含:

Line without anything interesting...
Line with Make failed 4
Line with Make failed 5
Line without...
Line without...

我提供的命令打印:

/tmp/u01/test/123.log:1:Line with Make failed 1
/tmp/u01/test/123.log:4:Line with Make failed 2
/tmp/u01/test/123.log:5:Line with Make failed 3

打破这个:

  1. awk 的-v选项意思是“在 awk 中设置这个变量”。
  2. RSFS意味着设置记录和字段分隔符。
  3. (上面链接)有关于如何设置RS特殊值""以使用多行记录的信息。
  4. 有关于设置FS为正则表达式的信息。在这种情况下,将字段分隔符设置为[:\n]表示“冒号或换行符”的正则表达式是有意义的。尝试awk -v RS="" -v FS="[:\n]" '{printf("$1: %s, $2: %s, $3: %s, $4: %s\n", $1, $2, $3, $4)}' commands-and-logs.txt了解字段是如何拆分的。
  5. 则表达式模式的意思是“仅向我显示 Command$2 ~ /apply|rollback/为 'apply' 或 'rollback' 的条目。”
  6. print $4打印第 4 个字段(日志文件名)。
  7. 我正在输入sort -u,所以我不会多次搜索文件。
  8. xargs grep搜索匹配的日志文件。我/dev/null基于这个技巧附加到参数列表中,以便始终在匹配行旁边列出文件名。

我希望这有帮助。


推荐阅读