ALARM/FATAL 키워드를 사용하여 내 로그 파일을 다른 백업 파일로 필터링하고 싶습니다. 다음 두 파일이 있다고 가정해 보겠습니다.
[root@TENCENT64 /tmp/test]# cat test_ccd.log
ccd0.log:01-28 09:33:18:461 1254 F NORMAL
ccd0.log:01-28 09:33:18:461 1254 F FATAL
ccd0.log:01-28 09:34:30:827 1254 E ALARM
[root@TENCENT64 /tmp/test]# cat test_mcd.log
mcd0.log:01-29 09:33:18:461 1254 F NORMAL
mcd0.log:01-29 09:33:18:461 1254 F FATAL
mcd0.log:01-29 09:34:30:827 1254 E ALARM
다음 백업 파일을 생성하고 싶습니다
[root@TENCENT64 /tmp/test]# cat test_ccd.log.txt
ccd0.log:01-28 09:33:18:461 1254 F FATAL
ccd0.log:01-28 09:34:30:827 1254 E ALARM
[root@TENCENT64 /tmp/test]# cat test_mcd.log.txt
mcd0.log:01-29 09:33:18:461 1254 F FATAL
mcd0.log:01-29 09:34:30:827 1254 E ALARM
이를 달성하기 위해 다음 명령을 시도했지만 그 중 아무 것도 작동하지 않았습니다. 누구든지 내가 잘못하고 있는 부분을 수정하도록 도와주실 수 있습니까?
[root@TENCENT64 /tmp/test]# cat /etc/redhat-release
CentOS Linux release 7.2 (Final)
# this commands hangs for ever
[root@TENCENT64 /tmp/test]# find . -name "*.log" -type f -exec sh -c 'grep -E "ALARM|FATA:" 1>>"$0.txt"' {} \;
# this commands reports the error and the output was missed up
[root@TENCENT64 /tmp/test]# find . -name "*.log" -type f -exec sh -c 'grep -R -E "ALARM|FATA:" 1>>"$0.txt"' {} \;
grep: input file ‘test_mcd.log.txt’ is also the output
grep: input file ‘test_ccd.log.txt’ is also the output
# the output for each file is not correct
[root@TENCENT64 /tmp/test]# cat test_mcd.log.txt
test_mcd.log:mcd0.log:01-29 09:34:30:827 1254 E ALARM
test_ccd.log:ccd0.log:01-28 09:34:30:827 1254 E ALARM
[root@TENCENT64 /tmp/test]# cat test_ccd.log.txt
test_mcd.log:mcd0.log:01-29 09:34:30:827 1254 E ALARM
test_ccd.log:ccd0.log:01-28 09:34:30:827 1254 E ALARM
test_mcd.log.txt:test_mcd.log:mcd0.log:01-29 09:34:30:827 1254 E ALARM
test_mcd.log.txt:test_ccd.log:ccd0.log:01-28 09:34:30:827 1254 E ALARM
다음 코드를 사용하여 백업 경고를 다른 위치에 저장하려고 하면 상황이 복잡해집니다. 백업 경고를 저장할 NFS 공유가 있고 각 경고는 공유의 폴더(IP 주소 이름을 따서 명명됨)에 개별적으로 저장됩니다. 다음은 내 명령입니다
# create the backed folder on the NFS share, like /data/backup/1.1.1.1/alarm_history
ip=`hostname -I|awk '{print $1}'` && mkdir -p /data/backup/${ip}/alarm_history
# iterate through /data/backup/1.1.1.1 to find all the alarms and persist into /data/backup/1.1.1.1/alarm_history, /data/backup is a shared base and 1.1.1.1 is mounted on the current server
ip=`hostname -I|awk '{print $1}'` && find /data/backup/${ip} -name '*.log' -type f -exec sh -c '
grep -E "ALARM|FATAL" "$1" >> "/data/backup/${ip}/alarm_history/$1.alarm" && sort -o "/data/backup/${ip}/alarm_history/$1.alarm" -u "/data/backup/${ip}/alarm_history/$1.alarm"
' 'find-sh' {} \;
두 가지 오류가 발생합니다.
find-sh: line 1: /data/backup//alarm_history//data/backup/11.62.17.249/manager/manager_mcd0.log.alarm: No such file or directory
find-sh: line 1: /data/backup//alarm_history//data/backup/11.62.17.249/manager/manager_mcd0_stat.log.alarm: No such file or directory
두 가지 문제가 있습니다. 1. "find" 명령에 전달된 ${ip}가 grep에서 인식되지 않습니다. 2. $1.alarm, $1은 grep의 절대 경로입니다. 기본 이름을 어떻게 알 수 있나요?
답변1
grep
매개변수가 누락되었으며 예상 결과를 얻으려면 매개 :
변수가 있어야 합니다 .L
grep -E "ALARM|FATA:" 1>> "$0.txt"
~해야 한다
grep -E "ALARM|FATAL" "$0" > "$0.txt"
(또는 결과를 기존 파일에 추가하려면 >>
또는 사용)1>>
$0
명령 이름과 위치 매개변수는 로 시작해야 하므로 이름 $1
을 추가하고 결과를 $1
스크립트에 전달할 수 있습니다.
find . -name '*.log' -type f -exec sh -c '
grep -E "ALARM|FATAL" "$1" > "$1.txt"
' 'find-sh' {} \;
sh
또는 가능한 적은 호출을 사용하여 결과를 반복합니다 {} +
.
find . -name '*.log' -type f -exec sh -c '
for file; do
grep -E "ALARM|FATAL" "$file" > "${file}.txt"
done
' 'find-sh' {} +
편집하다:
첫 번째 인수로 스크립트에 전달되는 대상 디렉터리에 대한 변수를 추가했습니다. 생성된 로그 파일을 정렬하기 위해 임시 파일을 사용합니다.
ip=$(hostname -I | awk '{ print $1 }')
targetdir="/data/backup/$ip/alarm_history"
mkdir -p "$targetdir"
find "/data/backup/$ip" -name '*.log' -type f -exec sh -c '
targetdir=$1; shift
for file; do
# extract the log filename from the path, append ".alarm", prepend directory
targetfile=${targetdir}/${file##*/}.alarm
grep -E "ALARM|FATAL" "$file" >> "$targetfile" \
&& mv "$targetfile" "${targetfile}.tmp" \
&& sort -o "$targetfile" -u "${targetfile}.tmp" \
&& rm "${targetfile}.tmp"
done
' 'find-sh' "$targetdir" {} +
답변2
for
이것은 루프로 더 쉬울 수 있습니다
예를 들어
for file in *.log
do
grep -E -- "ALARM|FATAL" "$file" > "$file.txt"
done