나는 어떤 작업을 수행한 다음 자체 로그 파일에 몇 줄을 추가하는 스크립트를 작성했습니다. 마지막 것만 남기고 싶어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.log
tail
설치하다
sponge
Debian 계열 시스템에 설치하려면:
apt-get install moreutils
RHEL/CentOS 시스템에 설치하려면 sponge
EPEL 저장소를 추가하고 다음을 수행하십시오.
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
열립니다 .file
n
잘림 없음와의 차이점은 <>;
리디렉션된 명령이 성공하면 ksh93
명령이 떠난 지점에서 fd에 대해 암시적 작업이 수행된다는 것입니다.ftruncate()
다른 쉘의 경우에도 동일한 작업을 수행할 수 있습니다.
{
tail -n 5 file.log &&
perl -e 'truncate STDOUT, tell STDOUT'
} 1<> file.log