我有一个文件foo.txt
,其中包含以下几行:
a
b
c
我想要一个简单的命令,导致foo.txt
的内容为:
a
b
答案 0 :(得分:343)
使用GNU sed
:
sed -i '$ d' foo.txt
早于3.95的-i
版本中不存在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
答案 1 :(得分:248)
这是迄今为止最快,最简单的解决方案,尤其是在大文件上:
head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt
如果你想删除顶行,请使用:
tail -n +2 foo.txt
表示从第2行开始的输出行。
不要使用sed
删除文件顶部或底部的行 - 如果文件很大,则速度非常慢。
答案 2 :(得分:103)
我在这里得到了所有答案的麻烦,因为我正在处理一个巨大的文件(~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
将覆盖文件到位,而不是复制(和解析)文件的每一行,这是其他解决方案所做的。
注意:这会从文件中删除该行!在虚拟文件上进行备份或测试,然后在自己的文件上进行尝试!
答案 3 :(得分:51)
要删除文件中的最后一行而不读取整个文件或重写任何内容,您可以使用
Sub DeleteCells()
Dim R As Range
'Set rng = Nothing
On Error Resume Next
Set R = Application.InputBox("Select cells To be deleted", Type:=8)
Dim rng As Range
Dim rngError As Range
Set rng = Sheets("Sheet3").Range("A1:G100")
Set rngError = rng.Cells.SpecialCells(xlCellTypeFormulas, xlErrors)
If TypeName(R) <> "Range" Then
Exit Sub
Else
R.delete
End If
For Each cell In rng
If cell.Text = "#REF!" Then
cell.EntireColumn.delete
End If
'delete means cells will move up after deleting that entire row
'rngError.EntireRow.ClearContents means that the contents will clear, leaving a blank cell for that entire row
Next
End Sub
要删除最后一行并在stdout上打印(&#34; pop&#34;它),您可以将该命令与tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}
结合使用:
tee
这些命令可以有效地处理非常大的文件。这与Yossi的答案类似,并受其启发,但它避免使用一些额外的功能。
如果您要反复使用这些并想要错误处理和其他一些功能,可以在此处使用tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})
命令:
https://github.com/donm/evenmoreutils
答案 4 :(得分:28)
Mac用户
如果您只想删除最后一行而不更改文件本身
sed -e '$ d' foo.txt
如果要删除输入文件的最后一行,请执行
sed -i '' -e '$ d' foo.txt
答案 5 :(得分:23)
在Mac上,头-n -1不会工作。并且,我试图找到一个简单的解决方案[不用担心处理时间],只使用“head”和/或“tail”命令来解决这个问题。
我尝试了以下命令序列,并且很高兴我可以使用“tail”命令[使用Mac上的选项]来解决它。因此,如果您使用的是Mac,并且只想使用“tail”来解决此问题,则可以使用此命令:
cat file.txt | tail -r |尾巴-n + 2 |尾巴-r
1&GT; tail -r:简单地反转其输入中的行的顺序
2 - ; tail -n +2:这将打印从输入
中的第二行开始的所有行答案 6 :(得分:12)
echo -e '$d\nw\nq'| ed foo.txt
答案 7 :(得分:8)
awk 'NR>1{print buf}{buf = $0}'
基本上,此代码说明如下:
对于第一行之后的每一行,打印缓冲行
每行,重置缓冲区
缓冲区滞后一行,因此最终会打印第1行到第n-1行
答案 8 :(得分:0)
awk "NR != `wc -l < text.file`" text.file |> text.file
这个片段可以解决问题。
答案 9 :(得分:0)
这两种解决方案都以其他形式存在。我发现这些更实用,更清晰,更有用:
使用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}
使用truncate:
BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
truncate -s $(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc ) ${ORIGINALFILE}
答案 10 :(得分:0)
这是您手动执行的操作(当我需要快速删除文件的最后一行时,我个人经常使用此方法):
vim + [FILE]
那里的+
符号表示在vim文本编辑器中打开文件时,光标将位于文件的最后一行。
现在只需在键盘上按两次d
。这将完全满足您的要求-删除最后一行。之后,先按:
,再按x
,然后按Enter
。这将保存更改,并带您回到Shell。因此,最后一行已被成功删除。
答案 11 :(得分:0)
sed '$d' ~/path/to/your/file/name
sed -i '' -e '$ d' ~/path/to/your/file/name
答案 12 :(得分:0)
您也可以尝试使用此方法:删除最后n行的示例。
a = 0; while [$ a -lt 4]; sed -i'$ d'output.txt; a =
expr $a + 1
;完成
从文件(output.txt)中删除最后4行。
答案 13 :(得分:0)
以下是使用海绵的解决方案(来自moreutils包):
head -n -1 foo.txt | sponge foo.txt
解决方案摘要:
如果您想为大型文件提供快速解决方案,请使用efficient tail或dd方法。
如果您想要一些易于扩展/调整和可移植的内容,请使用redirect and move方法。
如果您希望轻松扩展/调整某些内容,则文件不会太大,可移植性(即取决于moreutils
包)不是问题,并且是方形裤子的粉丝,请考虑使用海绵方法。
与“重定向和移动”方法相比,海绵方法的一个好处是海绵可以保留文件权限。
与“重定向和移动”方法相比,海绵使用了更多的RAM。这样可以提高速度(仅约20%),但是如果您对速度感兴趣,则可以采用“有效尾巴”和dd方式。
答案 14 :(得分:0)
可以处理大量数据,输出也可以,但有一个垃圾行。
如果我将脚本的输出通过管道传输到:
| sed -i '$ d' 我会得到以下错误,最后根本没有输出 sed:没有输入文件
但是| head -n -1 成功了!
答案 15 :(得分:-4)
红宝石(1.9 +)
ruby -ne 'BEGIN{prv=""};print prv ; prv=$_;' file