如何弹出(读取和删除)文件的一行?

如何弹出(读取和删除)文件的一行?

我试图获取文件的最后一行然后将其删除:

阅读该行:

sed -n '$p' file
# or
tail -n 1 file

删除该行:

sed -i '$d' file

这可行,但是有没有办法做到这一点单个命令

答案1

无论普遍的观点是什么,每次都必须读取整个文件才能截断其最后一行哑的,无论它是在单个进程/命令中还是在两个或三个进程/命令中完成。

与 不同的是sed -itail它足够聪明,不会从头读取文件以确定其最后一行是什么;另外,linux 有一个truncate(1)实用程序,它tail可以让您在 O(1) 时间内“弹出”一个大文件的最后一行:

# usage popline file [line_count, 1 by default]
popline()(LC_CTYPE=C; l=`tail -n "${2:-1}" "$1"; echo t`; l=${l%t}; truncate -s "-${#l}" "$1"; printf %s "$l")

$ wc -l /tmp/foo
3579500 /tmp/foo
$ cp /tmp/foo /tmp/foo1 && time sed -i '$d' /tmp/foo1

real    0m1.077s
user    0m0.457s
sys     0m0.156s
$ cp /tmp/foo /tmp/foo1 && time popline /tmp/foo1
 */

real    0m0.052s
user    0m0.002s
sys     0m0.003s

答案2

目标是使用一个命令输出文件的最后一行,同时从原始文件中删除该行。

sed -i -e '${w /dev/stdout' -e 'd;}' file

这将运行以下sed脚本:

${
    w /dev/stdout
    d
}

这将写入最后一行/dev/stdout,然后将其删除。所有其他行都通过该选项写回原始文件-i

命令行上的脚本必须分成两部分,因为无法以其他方式分隔命令的输出文件名w(除了插入文字换行符之外)。

ed

ed -s file <<END_ED
p
d
w
END_ED

ed打开文件file并将光标置于文件的最后一行。第一个命令将该行打印到标准输出,第二个命令删除它,最后一个命令将缓冲区写回文件。对于大文件,可能不建议使用ed这种方式。

相关内容