foo.txt
,其中包含以下几行:a
b
c
我想要一个简单的命令,该命令导致
foo.txt
的内容为:a
b
#1 楼
使用GNU sed
:sed -i '$ d' foo.txt
-i
版本在3.95之前的版本中不存在GNU sed
选项,因此您必须将其用作带有临时文件的过滤器:cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp
当然,在这种情况下,您也可以使用
head -n -1
而不是sed
。MacOS:
在Mac OS上X(从10.7.4版本开始),与上述
sed -i
命令的等效项为sed -i '' -e '$ d' foo.txt
#2 楼
这是迄今为止最快,最简单的解决方案,尤其是在大文件上:head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt
如果要删除顶行,请使用以下命令:
tail -n +2 foo.txt
,这意味着输出行从第2行开始。
请勿使用
sed
删除文件顶部或底部的行-如果文件很大。 评论
头-n -1 foo.txt就足够了
–ДМИТРИЙМАЛИКОВ
13年4月19日在23:57
head -n -1在bdsutils的head上不起作用。至少在macos使用的版本中不这样,所以这不起作用。
– johannes_lalala
15年1月22日在11:49
@johannes_lalala在Mac上,您可以brew安装coreutils(GNU核心实用程序)并使用ghead代替head。
–有趣的是
15年8月10日在14:12
这是一个简单的bash脚本,当您有多个文件的底部要删除的行数不同时,该脚本可以自动执行以下操作:cat TAILfixer FILE = $ 1; TAIL = $ 2; head -n-$ {TAIL} $ {FILE}> temp; mv temp $ {FILE}运行它以从myfile中删除4行,例如:./TAILfixer myfile 4首先要使其通过chmod + x TAILfixer可执行。
–法提赫·萨里戈尔(FatihSarigol)
18-3-28在21:11
竖起大拇指是因为它起作用了,但是对于所有与sed的比较,该命令也相当慢
– Jeff Diederiks
18年5月31日在15:32
#3 楼
我在这里遇到的所有问题都遇到了麻烦,因为我正在使用巨大的文件(〜300Gb),并且没有一种解决方案可以扩展。这是我的解决方案:dd if=/dev/null of=<filename> bs=1 seek=$(echo $(stat --format=%s <filename> ) - $( tail -n1 <filename> | wc -c) | bc )
换句话说:找出要结束的文件的长度(文件长度减去最后一行的长度,使用
bc
),并将该位置设置为文件的末尾(通过dd
将/dev/null
的一个字节写入文件的末尾)。 这是快速的,因为
tail
从头开始读取,并且dd
会覆盖文件,而不是复制(和解析)文件的每一行,这是其他解决方案所做的。注意:这会将行从文件中删除!在尝试对自己的文件进行备份之前,请对虚拟文件进行备份或测试!
评论
我什至不知道dd。这应该是最佳答案。非常感谢!遗憾的是,该解决方案不适用于(阻止)压缩文件。
–tommy.carstensen
2014-09-25 11:46
非常非常聪明的方法!请注意:它需要并在真实文件上运行,因此不能在管道,命令替换,重定向和此类链上使用。
–MestreLion
15年8月30日在11:37
这应该是最佳答案。立即为我的〜8 GB文件工作。
– Peter Cogan
16年1月9日在21:08
Mac用户:dd if = / dev / null of = <文件名> bs = 1 seek = $(echo $(stat -f =%z <文件名> | cut -c 2-)-$(tail -n1 <文件名> | wc -c)| bc)
–伊戈尔
16-4-5在14:49
这种方法是处理大文件的方法!
–thomas.han
17年8月3日,下午5:53
#4 楼
要从文件中删除最后一行而不读取整个文件或重写任何内容,可以使用tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}
删除最后一行并在stdout上打印它(“ pop”),则可以将该命令与
tee
结合使用:tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})
这些命令可以有效地处理非常大的文件。这与Yossi的答案相似并受其启发,但是避免了使用一些额外的功能。
如果您要重复使用这些功能并且想要错误处理和其他一些功能,则可以在此处使用
poptail
命令:https://github.com/donm/evenmoreutils
评论
快速说明:截断默认情况下在OS X上不可用。但是使用Brew进行安装很容易:brew install truncate。
–纪尧姆·布德罗(Guillaume Boudreau)
16年2月1日在20:44
非常好。没有dd会更好。我对将dd用作单个错位的数字或字母会造成灾难表示恐惧。.+1
–尤西·法琼(Yossi Farjoun)
16年6月12日在5:30
(笑话)实际上,(“ dd”->“ disaster”)需要1次替换和6次插入;几乎不是“单个错位的数字或字母”。 :)
–凯尔
18年5月23日在21:20
#5 楼
Mac用户
如果只希望最后一行删除输出而不更改文件本身,请这样做
sed -e '$ d' foo.txt
如果要删除输入文件本身的最后一行,请执行
sed -i '' -e '$ d' foo.txt
评论
这对我有用,但我听不懂。无论如何,它奏效了。
–梅尔文
18-10-11在12:04
标志-i''指示sed在就地修改文件的同时,将备份保留在文件中,并将扩展名作为参数提供。由于该参数为空字符串,因此不会创建备份文件。 -e告诉sed执行命令。命令$ d的意思是:找到最后一行($)并删除它(d)。
– Krzysztof Szafranek
19 Mar 3 '19 at 14:05
#6 楼
对于Mac用户:在Mac上,头-n -1不起作用。而且,我试图找到一种简单的解决方案[无需担心处理时间]仅使用“ head”和/或“ tail”命令来解决此问题。
我尝试了以下命令顺序,我很高兴我可以使用“ tail”命令(使用Mac上的可用选项)解决此问题。因此,如果您使用的是Mac,并且只想使用“ tail”来解决此问题,则可以使用以下命令:cat file.txt |尾-r |尾-n +2 | tail -r
说明:
1> tail -r:仅颠倒其输入中的行顺序
2> tail -n +2:这将从输入中的第二行开始打印所有行
评论
使用Homebrew安装coreutils将为您提供GNU头为“ ghead”,使您可以进行ghead -n -1
–有点不对劲
18 Mar 9 '18 at 15:31
#7 楼
echo -e '$d\nw\nq'| ed foo.txt
评论
对于未在适当位置编辑文件的过滤器解决方案,请使用sed'$ d'。
–lhf
2011年2月3日,下午1:59
#8 楼
awk 'NR>1{print buf}{buf = q4312078q}'
本质上,该代码表示以下内容:
对于第一行之后的每一行,打印缓冲行
,为每行重置缓冲区
缓冲区滞后了一行,因此您最终将第1行打印到n-1
评论
此解决方案是一个筛选器,不会在适当位置编辑文件。
–lhf
2011年2月3日,下午1:58
#9 楼
Linux$是最后一行,d表示删除:
sed '$d' ~/path/to/your/file/name
MacOS
与sed等效- i
sed -i '' -e '$ d' ~/path/to/your/file/name
#10 楼
awk "NR != `wc -l < text.file`" text.file |> text.file
这个代码可以解决问题。
评论
这只是为我删除了整个文件。
– Kartik Chugh
20年5月6日在17:21
#11 楼
这两种解决方案都以其他形式出现。我发现这些更加实用,清晰和有用:使用dd:
BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
dd if=${ORIGINALFILE} of=${ORIGINALFILE}.tmp status=none bs=1 count=$(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc )
/bin/mv -f ${ORIGINALFILE}.tmp ${ORIGINALFILE}
使用截断:
BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
truncate -s $(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc ) ${ORIGINALFILE}
评论
哎哟。方式太复杂了。
–罗伯特
19年1月6日在23:22
#12 楼
手动操作的方法如下(当我需要快速删除文件的最后一行时,我个人经常使用此方法):vim + [FILE]
那个
+
在那里签名表示在vim文本编辑器中打开文件时,光标将位于文件的最后一行。现在只需在键盘上按
d
两次。这将完全满足您的要求-删除最后一行。之后,按:
,然后按x
,然后按Enter
。这将保存更改并将您带回外壳。现在,最后一行已成功删除。评论
这里没有强调简单性
–彼得
19/12/27在13:02
#13 楼
您也可以尝试这种方法:删除最后n行的示例。a = 0; while [$ a -lt 4]; sed -i'$ d'output.txt; a =
expr $a + 1
;完成从文件(output.txt)中删除最后4行。
#14 楼
以下是使用海绵的解决方案(来自moreutils软件包):head -n -1 foo.txt | sponge foo.txt
解决方案摘要:
如果您想要快速解决大型文件的问题,请使用高效的尾巴或dd方法。
如果您想要一些易于扩展/调整和便携的方法,请使用重定向和移动方法。
如果您想要一些易于扩展/调整的东西,文件不要太大,可移植性(即取决于
moreutils
包)不是问题,并且您是方形裤子的粉丝,请考虑使用海绵方法。与“重定向和移动”方法相比,海绵方法的一个好处是海绵可以保留文件权限。
与“重定向和移动”方法相比,海绵使用的内存要多得多。这样可以提高速度(仅约20%),但是如果您对速度感兴趣,则可以使用“有效尾巴”和dd方法。
#15 楼
Ruby(1.9+)ruby -ne 'BEGIN{prv=""};print prv ; prv=$_;' file
评论
在Mac OS X上(自10.7.4起),与sed -i命令等效的是sed -i''-e'$ d'foo.txt。另外,head -n -1目前在Mac上无法使用。
–mklement0
2012年6月8日在22:15
您能解释一下'$ d'正则表达式的作用吗?这是关于删除最后一行的问题,所以我认为这对于每个查看此问题的人来说都是最重要的部分。谢谢 :)
– Kravemir
13年4月4日在12:47
@Miro:$ d绝对不是正则表达式。这是一个sed命令。 d是删除行的命令,而$表示“文件中的最后一行”。在命令前指定位置(在sed lingo中称为“范围”)时,该命令仅应用于指定位置。因此,此命令明确表示“在文件的最后一行的范围内,将其删除”。如果您要我的话,很滑而直截了当。
–丹尼尔·卡米尔·科扎尔(Daniel Kamil Kozar)
2014年6月4日在8:37
仅当空行时,如何删除最后一行?
– skan
17年1月16日在11:09
@Alex:已针对GNU sed更新;不知道各种BSD / UNIX / MacOS sed版本...
– thkala
17年1月23日在21:44