从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