dr_*_*dr_ 38 logs tail text-processing
我写的一个脚本做了一些事情,最后,在它自己的日志文件中附加了一些行。我只想保留日志文件的最后 n 行(比如 1000 行)。这可以在脚本的末尾以这种方式完成:
tail -n 1000 myscript.log > myscript.log.tmp
mv -f myscript.log.tmp myscript.log
Run Code Online (Sandbox Code Playgroud)
但是有更干净优雅的解决方案吗?也许通过单个命令完成?
par*_*ark 43
这是可能的,但正如其他人所说,最安全的选择是生成一个新文件,然后移动该文件以覆盖原始文件。
下面的方法将行加载到 BASH 中,因此根据来自 的行数tail
,这将影响本地 shell 用于存储日志行内容的内存使用情况。
如果空行存在于日志文件的末尾(由于 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
Run Code Online (Sandbox Code Playgroud)
Joh*_*024 29
该实用程序sponge
专为这种情况而设计。如果你安装了它,那么你的两行可以写成:
tail -n 1000 myscript.log | sponge myscript.log
Run Code Online (Sandbox Code Playgroud)
通常,在写入文件的同时读取文件是不可靠的。 sponge
通过myscript.log
在tail
完成读取并终止管道之后才写入来解决此问题。
sponge
在类似 Debian 的系统上安装:
apt-get install moreutils
Run Code Online (Sandbox Code Playgroud)
要sponge
在 RHEL/CentOS 系统上安装,请添加 EPEL 存储库,然后执行:
yum install moreutils
Run Code Online (Sandbox Code Playgroud)
来自man sponge
:
sponge
读取标准输入并将其写出到指定的文件。与 shell 重定向不同,sponge
它在写入输出文件之前吸收所有输入。这允许构建读取和写入同一文件的管道。
绝对“tail + mv”要好得多!但是对于 gnu sed 我们可以尝试
sed -i -e :a -e '$q;N;101,$D;ba' log
Run Code Online (Sandbox Code Playgroud)