How do you keep only the last n lines of a log file?
It is possible like this, but as others have said, the safest option is the generation of a new file and then a move of that file to overwrite the original.
The below method loads the lines into BASH, so depending on the number of lines from tail
, that's going to affect the memory usage of the local shell to store the content of the log lines.
The below also removes empty lines should they exist at the end of the log file (due to the behaviour of BASH evaluating "$(tail -1000 test.log)"
) so does not give a truly 100% accurate truncation in all scenarios, but depending on your situation, may be sufficient.
$ wc -l myscript.log
475494 myscript.log
$ echo "$(tail -1000 myscript.log)" > myscript.log
$ wc -l myscript.log
1000 myscript.log
The utility sponge
is designed just for this case. If you have it installed, then your two lines can be written:
tail -n 1000 myscript.log | sponge myscript.log
Normally, reading from a file at the same time that you are writing to it is unreliable. sponge
solves this by not writing to myscript.log
until after tail
has finished reading it and terminated the pipe.
Install
To install sponge
on a Debian-like system:
apt-get install moreutils
To install sponge
on a RHEL/CentOS system, add the EPEL repo and then do:
yum install moreutils
Documentation
From man sponge
:
sponge
reads standard input and writes it out to the specified file. Unlike a shell redirect,sponge
soaks up all its input before writing the output file. This allows constructing pipelines that read from and write to the same file.
definitely "tail + mv" is much better! But for gnu sed we can try
sed -i -e :a -e '$q;N;101,$D;ba' log