如何用其他文本替换部分系统日志尾部



我有一个系统日志,看起来像:

[timestamp]: [eventA] the system has started.
[timestamp]: [eventB] eventB detail is stored at <filepath>

<filepath>看起来像"/var/usr/eventB_timestamp.txt"

我通常不会查看整个日志,因为它是不断生成的,所以我通常使用"tail -F <logpath>"来查看这些事件。例如,主要的困难是我必须手动打开<filepath>才能看到事件B。这是非常低效的。如何替换消息行:

[timestamp]: [eventB] eventB detail is stored at <filepath>

带有

[timestamp]: [eventB] + content of <filepath>

我想到了一些单独的东西——grep然后是sed/awk。由于我是shell脚本的新手,有可靠的方法可以实现这一点吗?谢谢

要打开相应记录详细文件的最后一个实例,可以执行此

tail ... | tac | awk '/eventB/{print $NF; exit}' | xargs cat

反转输出,找到第一个模式,提取文件名并打印内容。

/tmp/test/file.log:

[timestamp]: [eventA] the system has started.
[timestamp]: [eventB] eventB detail is stored at /tmp/test/evenlog.file
[timestamp]: [eventC] foo foo foo.

/tmp/test/evenlog.file:

line 1
line 2
line 3

运行命令:

sed 's/(.*[eventB].*stored.at.)(.*)/printf [*EventB*]:;cat 2 | xargs echo /e' /tmp/test/file.log

输出:

[timestamp]: [eventA] the system has started.
[*EventB*]:line 1 line 2 line 3
[timestamp]: [eventC] foo foo foo.

问候,

这就是您想要的吗?

#!/bin/sh
tail -F logfile | while read line; do
  echo "$line"
  case "$line" in
    *"eventB detail is stored at"*)
      filepath="${line##* }"
      if [ -f "$filepath" ]; then
        sed 's/^/    /' "$filepath"
      else
        echo "ERROR: file missing"
      fi
      ;;
  esac
done

这会跟踪日志,读取并打印每一行,然后对于与模式匹配的行,将该行的最后一个字作为$filepath,如果存在同名文件,则打印该文件。。indended,为了你的阅读乐趣。


您可以在awk中实现相同的功能,只需较少的键入:

tail -F logfile | awk '
   1;
   /eventB detail is stored at/ {
      file=$NF
      while (getline < file) {
         printf("t%sn", $0);
      }
      close(file)
   }
'

请注意,如果有问题的文件不存在,这个awk解决方案会非常失败。因此,如果你使用awk解决方案,这可能是你的起点,但不应该是你的最终解决方案。YMMV。不对使用或误用负责。可能含有螺母。

最新更新