Answers:
使用GNU sed
:
sed -i '$ d' foo.txt
该-i
选项在GNU sed
3.95之前的版本中不存在,因此您必须将其用作带有临时文件的过滤器:
cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp
当然,在这种情况下,您也可以使用head -n -1
代替sed
。
苹果系统:
在Mac OS X(自10.7.4版)上,上述sed -i
命令等效于
sed -i '' -e '$ d' foo.txt
$ d
正则表达式。这是一个sed命令。d
是删除行的命令,而$
表示“文件中的最后一行”。在命令前指定位置(在sed lingo中称为“范围”)时,该命令仅应用于指定位置。因此,此命令明确表示“在文件的最后一行的范围内,将其删除”。如果您要我的话,很滑而直截了当。
这是迄今为止最快,最简单的解决方案,尤其是在大文件上:
head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt
如果要删除第一行,请使用以下命令:
tail -n +2 foo.txt
这意味着输出线从第2行开始。
请勿sed
用于删除文件顶部或底部的行-如果文件很大,这将非常慢。
head -n -1 foo.txt
够
brew install coreutils
(GNU核心实用程序)使用ghead
而不是head
。
FILE=$1; TAIL=$2; head -n -${TAIL} ${FILE} > temp ; mv temp ${FILE}
运行它删除4条线路,例如从MYFILE为:./TAILfixer myfile 4
当然首先要成为可执行chmod +x TAILfixer
sed
,该命令的执行速度也相当慢
我在这里遇到的所有答案都遇到了麻烦,因为我正在使用巨大的文件(〜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
会覆盖原位文件,而不是复制(和解析)文件的每一行,这是其他解决方案所做的。
注意:这将从文件中删除该行!在尝试对自己的文件进行备份之前,请对虚拟文件进行备份或测试!
要从文件中删除最后一行而不读取整个文件或重写任何内容,可以使用
tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}
要删除最后一行并在stdout上打印(“弹出”它),可以将该命令与tee
:
tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})
这些命令可以有效地处理非常大的文件。这与Yossi的答案相似并受其启发,但是避免了使用一些额外的功能。
如果您要重复使用这些功能并想要错误处理和其他一些功能,则可以在poptail
此处使用命令:https :
//github.com/donm/evenmoreutils
truncate
默认情况下在OS X上不可用。但是使用Brew:安装很容易brew install truncate
。
Mac用户
如果只希望最后一行删除输出而不更改文件本身,
sed -e '$ d' foo.txt
如果要删除输入文件本身的最后一行,请执行
sed -i '' -e '$ d' foo.txt
-i ''
告诉sed在就地修改文件的同时,将备份保留在文件中,并将扩展名作为参数提供。由于该参数为空字符串,因此不会创建备份文件。-e
告诉sed执行命令。该命令的$ d
意思是:找到最后一行($
)并将其删除(d
)。
在Mac上,head -n -1不起作用。而且,我试图找到一种简单的解决方案[无需担心处理时间]仅使用“ head”和/或“ tail”命令来解决此问题。
我尝试了以下命令序列,并很高兴我可以仅使用“ tail”命令(使用Mac上的可用选项)来解决它。因此,如果您使用的是Mac,并且只想使用“ tail”来解决此问题,则可以使用以下命令:
猫file.txt | 尾-r | 尾-n +2 | 尾巴
1> tail -r:简单地反转其输入中的行顺序
2> tail -n +2:这将从输入中的第二行开始打印所有行
ghead -n -1
这两种解决方案都采用其他形式。我发现这些更加实用,清晰和有用:
使用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}
sed -i
命令等效于sed -i '' -e '$ d' foo.txt
。另外,head -n -1
目前在Mac上无法使用。