从Bash中的文件中删除最后一行

我有一个文件, foo.txt ,包含以下几行:

 a b c 

我想要一个简单的命令,导致foo.txt的内容是:

 a b 

使用GNU sed

 sed -i '$ d' foo.txt 

-i选项在3.95以前的GNU sed版本中不存在,因此您必须将其用作具有临时文件的filter:

 cp foo.txt foo.txt.tmp sed '$ d' foo.txt.tmp > foo.txt rm -f foo.txt.tmp 

当然,在这种情况下,您也可以使用head -n -1而不是sed

这是迄今为止最快,最简单的解决scheme,特别是在大文件上:

 head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt 

如果你想删除顶部行使用这个:

 tail -n +2 foo.txt 

这意味着输出线从第2行开始。

不要使用sed删除文件顶部或底部的行 – 如果文件很大,速度非常慢。

我在这里的所有答案都遇到了麻烦,因为我正在使用一个巨大的文件(〜300Gb),没有解决scheme。 这是我的解决scheme:

 dd if=/dev/null of=<filename> bs=1 seek=$(echo $(stat --format=%s <filename> ) - $( tail -n1 <filename> | wc -c) | bc ) 

用文字说明:找出想要结束的文件长度(文件长度减去最后一行长度,使用bc ),并将该位置设置为文件末尾(用一个字节/dev/null到它上面)。

这是很快的,因为tail从头开始读取,而dd将覆盖文件而不是复制(和parsing)文件的每一行,这是其他解决scheme所做的。

注意:这将从文件中删除行! 在虚拟文件上进行备份或testing,然后在自己的文件上进行尝试!

要从文件中删除最后一行而不读取整个文件或重写任何内容 ,可以使用

 tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{} 

要删除最后一行,并打印在标准输出(“popup”它),你可以结合该命令与tee

 tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{}) 

这些命令可以有效地处理一个非常大的文件。 这与Yossi的答案类似,并且受到启发,但它避免了使用一些额外的function。

如果你打算重复使用这些,并想要error handling和一些其他function,你可以在这里使用poptail命令: https : //github.com/donm/evenmoreutils

Mac用户

如果你只想把最后一行删除输出而不改变文件本身的话

sed -e '$ d' foo.txt

如果你想删除input文件本身的最后一行呢

sed -i '' -e '$ d' foo.txt

 echo -e '$d\nw\nq'| ed foo.txt 
 awk 'NR>1{print buf}{buf = $0}' 

本质上,这个代码说明了以下内容:

在第一行之后,打印缓冲的行

对于每一行,重置缓冲区

缓冲区滞后一行,因此最终打印行1到n-1

对于Mac用户:

在Mac上,头-n -1不会工作。 而且,我试图find一个简单的解决scheme[不用担心处理时间],只用“head”和/或“tail”命令来解决这个问题。

我尝试了下面的一系列命令,很高兴我可以用“tail”命令[用Mac上提供的选项]来解决它。 所以,如果你在Mac上,并且只想用“尾巴”来解决这个问题,你可以使用这个命令:

cat file.txt | tail -r | tail -n +2 | tail -r

说明:

1> tail -r:简单地反转其input中的行的顺序

2> tail -n +2:打印input中从第二行开始的所有行

 awk "NR != `wc -l < text.file`" text.file |> text.file 

这段代码可以做到这一点。

ruby(1.9+)

 ruby -ne 'BEGIN{prv=""};print prv ; prv=$_;' file