【发布时间】:2012-08-23 23:28:37
【问题描述】:
我问过question关于在 PHP 中弹出文本文件的最后一行的问题,现在,是否可以在 shell 脚本中重写逻辑?
我试过这个来获取最后一行:
tail -n 1 my_log_file.log
但我不确定如何删除最后一行并保存文件。
附:鉴于我使用的是 Ubuntu 服务器。
【问题讨论】:
我问过question关于在 PHP 中弹出文本文件的最后一行的问题,现在,是否可以在 shell 脚本中重写逻辑?
我试过这个来获取最后一行:
tail -n 1 my_log_file.log
但我不确定如何删除最后一行并保存文件。
附:鉴于我使用的是 Ubuntu 服务器。
【问题讨论】:
要获取没有最后一行的文件内容,可以使用
head -n-1 logfile.log
(我不确定这是否在所有地方都支持)
或
sed '$d' logfile.log
【讨论】:
您想要的是在最后一行之前截断文件,而不必完全读取文件。
truncate -s -"$(tail -n1 file | wc -c)" file
这是假设文件当前没有被写入。
truncate 是 GNU coreutils 的一部分(通常出现在最近的 Linux 发行版中),它不是标准化的 Unix 或 POSIX 命令。许多“dd”实现也可用于截断文件。
【讨论】:
tail + truncate 确实是一个更有效的解决方案。自然,为了让 OP 检索最后一行 tail -n 的内容,应该单独调用并存储在 var 中。然后您可以使用${#VAR} + 1 作为截断大小。
-r 选项(使用给定文件的大小):truncate -r <(tail -n1 file) file。
(解决方案基于sch's answer,因此应归功于他/她)
这种方法将允许您有效地检索文件的最后一行并截断文件以删除该行。这可以更好地处理大输入,因为文件不是按顺序读取的。
# retrieve last line from file
LAST=$(tail -n 1 my_log_file.log)
# truncate file
let TRUNCATE_SIZE="${#LAST} + 1"
truncate -s -"$TRUNCATE_SIZE" my_log_file.log
# ... $LAST contains 'popped' last line
请注意,如果在调用 tail 和 truncate 之间修改了文件,这将无法正常工作。
【讨论】:
truncate 需要以 字节 为单位的大小,而 ${#LAST} 以字符数计算 $LAST 的长度。您希望将语言环境设置为 C 以使其等效。否则,如果最后一行包含多字节字符,这将无法正常工作。
一种方法是:
sed '$d' < f1 > f2 ; mv f2 f1
【讨论】:
f2 和 f1 是什么?
-i,因为它在 macOS 和 Linux 上是不同的。