如何在跟踪日志文件时从 awk 调用 sed?

如何在跟踪日志文件时从 awk 调用 sed?

我应该跟踪日志文件,我想sed在日志中出现特定行时启动命令来编辑配置文件。我做了很少的研究,发现它可以用 来完成awk

语法如下:

tail -f /path/to/serverLog | awk '
                    /Printer is on fire!/ { system("shutdown -h now") }
                    /new USB high speed/  { system("echo \"New USB\" | mail admin") }'

如本文中所提议的回答

所以我自己写了一个sed变体:

tail -f logfile | awk '/^Jit ended**/  { system("sed -E '/^Jit/{s/enabled=false/enabled=true/; s/From=[0-9]+-[0-9]+-[0-9]+/From=2021-02-01/}' conffile") }'

但它不起作用,并抛出类似的错误

(^ syntax error|^ unterminated string)

{}我想这是在命令中做一些与语法sed不兼容的事情awk,但不知道到底在哪里,以及如何让它工作。

答案1

通过调用 awk 来调用您正在执行的其他命令:

shell { awk { system { subshell { cmd } } } }

而不是简单地

shell { cmd }

这是非常低效和脆弱的。

我能告诉你的最好的事情应该是做类似的事情(未经测试):

while IFS= read -r line; do
    case $line in
        *"Printer is on fire!"* ) shutdown -h now ;;
        *"new USB high speed"* )  echo 'New USB' | mail admin ;;
        "Jit ended"* )            tmp=$(mktemp) &&
                                  sed 's/foo/bar/' conffile > "$tmp" &&
                                  mv -- "$tmp" conffile
                                  ;;
    esac
    sleep 1
done < '/path/to/serverLog'

答案2

您可以使用 GNUawk's替换函数sub,给定来自您的示例输入上一个问题,并使用就地扩展写入文件(在执行命令之前始终进行备份):

$ cat conffile
Jit .... enabled=false
Jit ..shoes.. From=2021-01-01
Jit ..gloves.. From=2021-01-01

$ tail -f logfile | while IFS= read -r i; do 
  if echo "$i" | grep '^Jit'; then
    awk -i inplace '/^Jit/ { sub(/=false$/, "=true"); sub(/[0-9\-]+$/, "2021-02-01"); print  }' conffile
    exit # exit if a match is found
  fi
done
$ cat conffile
Jit .... enabled=true
Jit ..shoes.. From=2021-02-01
Jit ..gloves.. From=2021-02-01

我应该添加我的评论我对这个问题的回答关于替换:

我提出了一个解决方案,假设(直到更全面的样本输入)线条具有严格的结束模式。如果是这样的话,就不需要更复杂的匹配。

并注意:我之所以使用,grep是因为我对 不够精通awk,我确信其他答案会更好(这个答案受到批评或纠正),但也许您可以了解一下您可以做什么。

相关内容