ログファイルを追跡する必要がありますが、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
他の答えがより良いと確信しているので、これを使用しています(この答えは批判または修正の対象です)。あなたができること。