从 Bash 中的文件中删除最后一行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4881930/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Remove the last line from a file in Bash
提问by Fragsworth
I have a file, foo.txt
, containing the following lines:
我有一个文件,foo.txt
包含以下几行:
a
b
c
I want a simple command that results in the contents of foo.txt
being:
我想要一个简单的命令,它的内容foo.txt
是:
a
b
回答by thkala
Using GNU sed
:
使用GNU sed
:
sed -i '$ d' foo.txt
The -i
option does not exist in GNU sed
versions older than 3.95, so you have to use it as a filter with a temporary file:
该-i
选项在GNU sed
3.95 之前的版本中不存在,因此您必须将其用作带有临时文件的过滤器:
cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp
Of course, in that case you could also use head -n -1
instead of sed
.
当然,在这种情况下,您也可以使用head -n -1
代替sed
.
MacOS:
苹果系统:
On Mac OS X (as of 10.7.4), the equivalent of the sed -i
command above is
在 Mac OS X 上(从 10.7.4 开始),sed -i
上面命令的等价物是
sed -i '' -e '$ d' foo.txt
回答by John
This is by far the fastest and simplest solution, especially on big files:
这是迄今为止最快和最简单的解决方案,尤其是在大文件上:
head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt
if You want to delete the top line use this:
如果要删除顶行,请使用以下命令:
tail -n +2 foo.txt
which means output lines starting at line 2.
这意味着从第 2 行开始的输出行。
Do not use sed
for deleting lines from the top or bottom of a file -- it's very very slow if the file is large.
不要sed
用于从文件的顶部或底部删除行——如果文件很大,它会非常慢。
回答by Yossi Farjoun
I had trouble with all the answers here because I was working with a HUGE file (~300Gb) and none of the solutions scaled. Here's my solution:
我在这里的所有答案都遇到了麻烦,因为我正在处理一个巨大的文件(~300Gb)并且没有一个解决方案可以扩展。这是我的解决方案:
dd if=/dev/null of=<filename> bs=1 seek=$(echo $(stat --format=%s <filename> ) - $( tail -n1 <filename> | wc -c) | bc )
In words: Find out the length of the file you want to end up with (length of file minus length of length of its last line, using bc
) and, set that position to be the end of the file (by dd
ing one byte of /dev/null
onto it).
在字:找出你想(长文件减去它的最后一行的长度的长度,使用,结束了该文件的长度bc
),并设定该位置是文件的末尾(由dd
荷兰国际集团的一个字节 /dev/null
到它)。
This is fast because tail
starts reading from the end, and dd
will overwrite the file in placerather than copy (and parse) every line of the file, which is what the other solutions do.
这很快,因为tail
从末尾开始读取,dd
并将覆盖文件原地而不是复制(和解析)文件的每一行,这是其他解决方案所做的。
NOTE: This removes the line from the file in place! Make a backup or test on a dummy file before trying it out on your own file!
注意:这会从文件中删除该行!在您自己的文件上尝试之前,请先备份或测试一个虚拟文件!
回答by ohspite
To remove the last line from a file without reading the whole file or rewriting anything, you can use
要从文件中删除最后一行而不读取整个文件或重写任何内容,您可以使用
tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}
To remove the last line and also print it on stdout ("pop" it), you can combine that command with tee
:
要删除最后一行并将其打印在标准输出上(“弹出”它),您可以将该命令与tee
:
tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})
These commands can efficiently process a very large file. This is similar to, and inspired by, Yossi's answer, but it avoids using a few extra functions.
这些命令可以有效地处理非常大的文件。这类似于 Yossi 的回答并受到其启发,但它避免了使用一些额外的功能。
If you're going to use these repeatedly and want error handling and some other features, you can use the poptail
command here:
https://github.com/donm/evenmoreutils
如果您要重复使用这些并想要错误处理和一些其他功能,您可以在poptail
此处使用命令:https:
//github.com/donm/evenmoreutils
回答by manpreet singh
Mac Users
Mac 用户
if you only want the last line deleted output without changing the file itself do
如果您只想删除最后一行的输出而不更改文件本身
sed -e '$ d' foo.txt
sed -e '$ d' foo.txt
if you want to delete the last line of the input file itself do
如果要删除输入文件本身的最后一行,请执行
sed -i '' -e '$ d' foo.txt
sed -i '' -e '$ d' foo.txt
回答by Sarfraaz Ahmed
For Mac Users :
对于 Mac 用户:
On Mac, head -n -1 wont work. And, I was trying to find a simple solution [ without worrying about processing time ] to solve this problem only using "head" and/or "tail" commands.
在 Mac 上, head -n -1 不起作用。而且,我试图找到一个简单的解决方案 [无需担心处理时间] 仅使用“head”和/或“tail”命令来解决这个问题。
I tried the following sequence of commands and was happy that I could solve it just using "tail" command [ with the options available on Mac ]. So, if you are on Mac, and want to use only "tail" to solve this problem, you can use this command :
我尝试了以下命令序列,很高兴我可以仅使用“tail”命令 [ 以及 Mac 上可用的选项 ] 来解决它。所以,如果你在 Mac 上,并且只想使用“tail”来解决这个问题,你可以使用这个命令:
cat file.txt | tail -r | tail -n +2 | tail -r
猫文件.txt | 尾巴 -r | 尾 -n +2 | 尾-r
Explanation :
解释 :
1> tail -r : simply reverses the order of lines in its input
1> tail -r :简单地颠倒其输入中的行顺序
2> tail -n +2 : this prints all the lines starting from the second line in its input
2> tail -n +2 :这将打印从其输入中的第二行开始的所有行
回答by lhf
echo -e '$d\nw\nq'| ed foo.txt
回答by Foo Bah
awk 'NR>1{print buf}{buf = awk "NR != `wc -l < text.file`" text.file |> text.file
}'
Essentially, this code says the following:
本质上,这段代码说明如下:
For each line after the first, print the buffered line
对于第一行之后的每一行,打印缓冲行
for each line, reset the buffer
对于每一行,重置缓冲区
The buffer is lagged by one line, hence you end up printing lines 1 to n-1
缓冲区滞后一行,因此您最终会打印第 1 到 n-1 行
回答by Michael Kingski
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}
This snippet does the trick.
这个片段可以解决问题。
回答by virtual-light
Both of these solutions are here in other forms. I found these a little more practical, clear, and useful:
这两种解决方案都以其他形式存在。我发现这些更实用、更清晰、更有用:
Using dd:
使用 dd:
BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
truncate -s $(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc ) ${ORIGINALFILE}
Using truncate:
使用截断:
##代码##