로그 파일을 추적해야 하는데 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
예제의 입력에 따라 GNU awk'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
다른 답변이 더 나을 것이라고 확신하기 때문에 이것을 사용하고 있습니다 (이 답변은 비판이나 수정의 대상입니다). 당신이 할 수 있는 것.