테스트 문자열과 일치하는 로그 파일의 마지막 줄을 가져와서 다른 로그 파일에 출력하고 싶습니다.
다양한 텍스트 문자열을 테스트하고 출력에 따라 다양한 로그 파일로 보내야 합니다.
나는 이것을 사용하고 있습니다 :
tail -f -n 1 input.log | grep string1 >>output1.log
그런 다음 다음과 같이 테스트를 반복하고 싶습니다.
tail -f -n 1 input.log | grep string2 >>output2.log
tail -f -n 1 input.log | grep string3 >>output3.log
효율적인 단일 bash 스크립트에서 이를 어떻게 달성할 수 있습니까?
답변1
grep 대신 awk를 사용하십시오.
awk '/string1/ { print >> "output1.log" ; fflush() }
/string2/ { print >> "output2.log" ; fflush() }
/string3/ { print >> "output3.log" ; fflush() }' input.log
이 출력모두행을 해당하는 output.log 파일과 일치시킵니다. 그것은 당신의 모순 tail -f
과 요구 사항을 이해할 수 없기 때문입니다 tail -n 1
. input.log
현재 마지막 줄에서 시작 하려면 tail -f -n 1
스크립트 를 파이프 awk
하고 input.log
해당 줄의 끝을 제거하십시오. 예를 들어
tail -f -n 1 input.log | awk '...same awk script as above...'
tee
당신은 또한 grep
그것을 할 수 있습니다 및프로세스 교체
(그러나 상당히 느려질 것입니다):
tee >(grep --line-buffered string1 >> output1.log) \
>(grep --line-buffered string2 >> output2.log) \
>(grep --line-buffered string3 >> output3.log) < input.log
또는
tail -f -n 1 input.log | tee .....
노트:fflush()
in -solution awk
및 in-solution --line-buffered
옵션은 (또는 다른 끝없는 프로세스)의 출력을 또는 으로 파이프하는 경우에만 필요합니다 .tee
tail -f
awk
tee
이것이 없으면 출력 파일은 출력 버퍼(awk 또는 grep)가 가득 찼을 때만 기록됩니다. 작업이 버퍼에 기록되지 않은 출력으로 중단되면(예: Ctrl-C를 누름) 모든 출력은 여전히 손실됩니다. 버퍼.
이를 사용하면 두 솔루션 모두 훨씬 느리게 실행됩니다(쓰기마다 출력을 플러시하기 때문에). 그러나 입력 파일이 매우 크지 않으면 문제가 되지 않습니다.
그건 그렇고, 이것은 입력이 끝날 때 문제가 되지 않습니다. 이 경우 awk와 grep은 모두 종료하기 전에 자동으로 출력 버퍼를 플러시합니다.
또 다른 대안은 서브쉘에서 파이프 awk
(또는)를 실행하여 Ctrl-C의 인터럽트 신호를 포착하고 무시하는 것입니다. tee
예를 들어
tail -f input.log | (
trap '' INT
awk '/string1/ { print >> "output1.log" }
/string2/ { print >> "output2.log" }
/string3/ { print >> "output3.log" }'
)
tail -f
Ctrl-C를 누르면 영향을 주지만(종료) 실행 중인 하위 쉘은 awk
이를 무시합니다. awk
출력 버퍼를 플러시하고 tail
입력이 완료되어 종료되면 종료됩니다.
바라보다awk 스크립트에서 Ctrl-C 캡처또 다른 예/설명.
로그 파일을 따르지 않으려면 tail
's -f
옵션을 사용하지 마세요.
tail -n 1 | .....
세 문자열 모두의 마지막 항목을 해당 출력 파일에 인쇄하는 Guy의 답변을 사용하거나 살펴보십시오 .
답변2
생산 라인에 집중할 수 있도록 CAS의 솔루션을 편집하세요.
테스트 문자열과 일치하는 로그 파일의 마지막 줄을 가져와서 다른 로그 파일에 출력하고 싶습니다.
awk '
# every time theres a match, save that line into a variable
/string1/ { str1 = $0 }
/string2/ { str2 = $0 }
/string3/ { str3 = $0 }
END {
# and only print to file after reading the whole log.
print str1 >> "output1.log"
print str2 >> "output2.log"
print str3 >> "output3.log"
}' input.log
답변3
입력 파일
praveen
ajay
abhi
praveen
ajay
abhi
kiran
tomato
우리의 요구 사항은 다른 텍스트 문자열을 검색하고 출력을 다른 텍스트 파일에 쓰는 것입니다.
동일한 목적을 달성하기 위해 for 루프 및 sed 명령을 사용했습니다.
praveen, ajay, abhi 콘텐츠 검색을 시도하고 결과를 contentsearch.txt에 저장했습니다.
스크립트
for i in praveen ajay abhi; do sed -n "/$i/p" input.txt > $i.txt; done
아래는 출력이 될 것입니다
praveen.txt will contains line where praveen is present
ajay.txt will contains line where ajay is present
abhi.txt will contains where abhi is present
================================================= = ============================
테스트 문자열과 일치하는 로그 파일의 마지막 줄을 검색하여 다른 파일에 출력하려면 다음 명령을 사용하십시오.
sed -n '/Contentsearch/p' input.txt | tail -1 > output.txt