我应该跟踪日志文件,我想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
,我确信其他答案会更好(这个答案受到批评或纠正),但也许您可以了解一下您可以做什么。