【问题标题】:How to replace part of the system log tail with other text?如何用其他文本替换部分系统日志尾部?
【发布时间】:2016-04-07 16:49:32
【问题描述】:

我的系统日志如下所示:

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

&lt;filepath&gt; 看起来像 "/var/usr/eventB_timestamp.txt"

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

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

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

我正在单独考虑grep 然后sed/awk。由于我对 shell 脚本非常陌生,有没有可靠的方法来完成这个?谢谢。

【问题讨论】:

    标签: linux bash awk sed


    【解决方案1】:

    要打开相应记录详细文件的最后一个实例,您可以这样做

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

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

    【讨论】:

      【解决方案2】:

      /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.
      

      问候,

      【讨论】:

        【解决方案3】:

        这就是你要找的吗?

        #!/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%s\n", $0);
              }
              close(file)
           }
        '
        

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

        【讨论】:

          猜你喜欢
          • 2020-12-04
          • 2015-12-16
          • 2021-09-14
          • 2013-07-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多