내 로그를 분석하는 프로젝트가 있는데 세 번 이상 발생하는 연속 오류를 찾아 로그 이름을 나열해야 합니다. 내 로그가 크기 때문에 다음 스크립트를 작성했습니다.
for i in `ls`
do
count=`uniq -c $i | grep 'FATAL ERROR' |sed 's/^ *//g'| sed 's/ /,/g' | awk -F',' '{if($1 >1) {print $1}}'`
if [[ $count -ge 2 ]]
then
echo $i
fi
done
이것은 모든 파일의 발생 횟수만 알아야 하는 경우에 작동합니다.
grep -o -c Source * | awk -F: '{if ($2 > 2){print $1}}'
내 스크립트의 더 나은 버전은 무엇입니까? 로그가 너무 커서 코드 속도가 느려지면 어떻게 되나요?
답변1
파이프는 일반적으로 짧게 유지되어야 하며, 값을 얻기 위해 수행하는 대부분의 작업은 루프 및 명령문을 포함하여 count
단일 프로그램에서 수행할 수 있습니다 .awk
if
awk 'FNR == 1 || !/FATAL ERROR/ { count = 0 }
/FATAL ERROR/ { ++count }
count == 2 { print FILENAME }' ./*
awk
그러면 현재 디렉터리에 숨겨져 있지 않은 모든 파일에 대해 단일 프로그램이 실행됩니다.
count
새 파일의 첫 번째 줄에 있으면 프로그램은 해당 변수를 0으로 재설정합니다.또는현재 행이 패턴과 일치하지 않는 경우 FATAL ERROR
.
행이 패턴과 일치하면 FATAL ERROR
변수 count
가 증가합니다.
count
변수의 값이 2에 도달하면 현재 파일의 이름이 인쇄됩니다 .
코드는 패턴과 일치하는 두 개의 연속 라인을 찾을 때마다 파일 이름을 인쇄합니다. 이는 동일한 파일에서 여러 번 발생하더라도 마찬가지입니다. 필요하지 않은 경우 코드를 약간 확장할 수 있습니다.
awk 'FNR == 1 { count = 0; do_print = 1 }
!/FATAL ERROR/ { count = 0 }
/FATAL ERROR/ { ++count }
count == 2 && do_print { print FILENAME; do_print = 0 }' ./*
또는 GNU를 사용하여 awk
( nextfile
다음 파일로 건너뛰기 위해):
awk 'FNR == 1 || !/FATAL ERROR/ { count = 0 }
/FATAL ERROR/ { ++count }
count == 2 && do_print { print FILENAME; nextfile }' ./*
쉘 루프와 관련: