로그 파일의 마지막 n줄만 유지하는 방법은 무엇입니까?

로그 파일의 마지막 n줄만 유지하는 방법은 무엇입니까?

나는 어떤 작업을 수행한 다음 자체 로그 파일에 몇 줄을 추가하는 스크립트를 작성했습니다. 마지막 것만 남기고 싶어N로그 파일의 줄 수(예: 1000줄). 이 작업은 스크립트 끝에서 다음을 통해 수행할 수 있습니다.

tail -n 1000 myscript.log > myscript.log.tmp
mv -f myscript.log.tmp myscript.log

하지만 더 깨끗하고 우아한 솔루션이 있을까요? 어쩌면 단일 명령으로 수행될 수 있습니까?

답변1

가능하지만 다른 사람들이 말했듯이 가장 안전한 옵션은 새 파일을 생성한 다음 원본 파일을 덮어쓰면서 해당 파일을 이동하는 것입니다.

다음 방법은 행을 BASH에 로드하므로 행 수에 따라 tail로그 행의 내용을 저장하는 로컬 셸의 메모리 사용량에 영향을 미칩니다.

다음은 BASH 평가 동작으로 인해 로그 파일 끝에 있는 빈 줄도 제거하므로 "$(tail -1000 test.log)"모든 경우에 실제로 100% 정확한 잘림을 제공하지는 않지만 경우에 따라 충분할 수 있습니다.

$ wc -l myscript.log
475494 myscript.log

$ echo "$(tail -1000 myscript.log)" > myscript.log

$ wc -l myscript.log
1000 myscript.log

답변2

이 유틸리티는 sponge이러한 상황을 위해 설계되었습니다. 설치했다면 두 줄은 다음과 같이 작성할 수 있습니다.

tail -n 1000 myscript.log | sponge myscript.log

일반적으로 파일을 쓰는 동안 파일을 읽는 것은 신뢰할 수 없습니다. 이 문제는 읽기가 완료되고 파이프가 종료될 때까지 sponge쓰지 않으면 해결됩니다 .myscript.logtail

설치하다

spongeDebian 계열 시스템에 설치하려면:

apt-get install moreutils

RHEL/CentOS 시스템에 설치하려면 spongeEPEL 저장소를 추가하고 다음을 수행하십시오.

yum install moreutils

문서

에서 man sponge:

sponge표준 입력을 읽고 지정된 파일에 씁니다. 쉘 리디렉션과 달리 sponge모든 입력은 출력 파일에 쓰기 전에 흡수됩니다. 이를 통해 동일한 파일을 읽고 쓰는 파이프라인을 구축할 수 있습니다.

답변3

확실히 "tail + mv"가 더 좋습니다! 하지만 gnu sed의 경우 시도해 볼 수 있습니다.

sed -i -e :a -e '$q;N;101,$D;ba' log

답변4

ksh93 셸에서:

$ seq -f 'This is line %g' 10000 > file.log
$ tail -n 5 file.log 1<>; file.log
$ cat file.log
This is line 9996
This is line 9997
This is line 9998
This is line 9999
This is line 10000

n<>; file표준 리디렉션 연산자 와 마찬가지로 fd 에서 읽기+쓰기 모드로 n<> file열립니다 .filen잘림 없음와의 차이점은 <>;리디렉션된 명령이 성공하면 ksh93명령이 떠난 지점에서 fd에 대해 암시적 작업이 수행된다는 것입니다.ftruncate()

다른 쉘의 경우에도 동일한 작업을 수행할 수 있습니다.

{
  tail -n 5 file.log &&
    perl -e 'truncate STDOUT, tell STDOUT'
} 1<> file.log

관련 정보