
몇 시간 후에 지속적으로 업데이트(새 줄 추가)되는 로그 파일이 있습니다.
10분마다 파일에서 오류 메시지만 가져옵니다.
처음에는 처음에 다음을 사용하여 "ERROR FOUND" 패턴과 일치하는 새 파일로 모든 줄을 가져왔습니다.앗.
그러나 10분 후에 로그 파일에 새 줄이 더 추가되었으므로 내가 떠난 로그 파일을 읽고 싶습니다. 다시 처음부터 시작하고 싶지 않아요.
이에 대한 최고의 코드나 스크립트를 제안해 줄 수 있는 사람이 있나요?
답변1
다음과 같은 파일 설명자에서 파일을 열면:
exec 3< /path/to/log/file
그런 다음 처리할 수 있습니다.
awk '...' <&3
awk
그 후 fd 3은 그것이 남겨진 곳을 가리킬 것입니다 .
10분 후에 동일한 셸 호출에서 다음을 실행할 수 있습니다.
awk '...' <&3
새로운 데이터를 처리하기 위해 다시 명령을 내리세요.
현재 위치를 저장하여 다른 쉘 호출에서 읽기를 재개할 수 있도록 하려면 다음을 ksh93
수행하십시오.
#! /usr/bin/env ksh93
file=/path/to/some-file
offset_file=$file.offset
exec 3< "$file"
[ -f "$offset_file" ] && exec 3<#(($(<"$offset_file")))
awk '...' <&3
echo "$(3<#((CUR)))" > "$offset_file"
또는 zsh를 사용하면 다음과 같습니다.
#! /usr/bin/env zsh
zmodload zsh/system
file=/path/to/some-file
offset_file=$file.offset
exec 3< $file
[ -f "$offset_file" ] && sysseek -u 3 "$(<$offset_file)"
awk '...' <&3
echo $((systell(3))) > $offset_file
답변2
나는 Stéphane의 답변이 전체 파일을 계속해서 읽지 않기 때문에 좋아하므로 여기에 다음을 추가합니다.세게 때리다seek
(Linux에서) 그의 솔루션과 동일합니다(bash에는 내장 기능 이나 기능이 없습니다 tell
). 댓글을 사용했을 텐데 평판이 너무 낮습니다.
LASTPOS=/tmp/saved_pos
exec 3< "$1"
test -f "$LASTPOS" && STARTPOS=$(($(<$LASTPOS)+1))
tail -c "+${STARTPOS:-1}" <&3 | grep "ERROR FOUND"
grep '^pos:' /proc/self/fdinfo/3 | cut -f2 > "$LASTPOS"
또한 일반적으로 더 빠르기 때문에 awk
명령을 로 대체했습니다 . 추가 처리가 필요한 경우 grep
출력을 명령으로 파이프할 수 있습니다 .awk
답변3
wc -l
나는 and 로 시도해 볼 것이다 tail
.
Bash를 사용하는 경우 다음과 같이 작동합니다.
#!/bin/bash
LASTLNFILE=/tmp/lastline # replace with a suitable path
test -f $LASTLNFILE && LASTLN=$(<$LASTLNFILE)
CURLN=$(wc -l $1 | cut -d' ' -f1)
if ((CURLN-LASTLN > 0)); then
tail -n $((CURLN-LASTLN)) $1
fi
echo $CURLN > $LASTLNFILE
PS는 이를 awk 프로그램 이전에 필터로 사용합니다. 예를 들어 이름을 'newlines.sh'라고 가정한다고 가정합니다.
./newlines.sh <log_file> | awk -f <your_awk_program>`
위의 스크립트를 방법의 예로 남겨두고 있습니다.하지 마세요. 이 글을 쓴 직후 스크립트가 실행되는 동안 로그 파일이 업데이트될 때마다 경쟁 조건에 취약하다는 것을 깨달았습니다.
순수한 AWK 접근 방식이 바람직합니다.
#!/bin/awk
BEGIN {
lastlinefile = "/tmp/lastlinefile"
getline lastline < lastlinefile
}
NR > lastline && /ERROR FOUND/ {
# do your stuff...
print
}
END { print NR > lastlinefile }