我有一个非常大的文件(约 400 GB),我需要从中删除最后两行。我尝试使用sed
,但它运行了几个小时才放弃。有没有快速的方法可以做到这一点,还是我只能使用sed
?
答案1
我还没有在大文件上尝试过这个来查看它的速度有多快,但它应该相当快。
要使用脚本从文件末尾删除行:
./shorten.py 2 large_file.txt
它寻找文件末尾,检查以确保最后一个字符是换行符,然后向后逐个读取每个字符,直到找到三个换行符,并在该点之后截断文件。更改已就位。
编辑:我在底部添加了一个 Python 2.4 版本。
以下是适用于 Python 2.5/2.6 的版本:
#!/usr/bin/env python2.5
from __future__ import with_statement
# also tested with Python 2.6
import os, sys
if len(sys.argv) != 3:
print sys.argv[0] + ": Invalid number of arguments."
print "Usage: " + sys.argv[0] + " linecount filename"
print "to remove linecount lines from the end of the file"
exit(2)
number = int(sys.argv[1])
file = sys.argv[2]
count = 0
with open(file,'r+b') as f:
f.seek(0, os.SEEK_END)
end = f.tell()
while f.tell() > 0:
f.seek(-1, os.SEEK_CUR)
char = f.read(1)
if char != '\n' and f.tell() == end:
print "No change: file does not end with a newline"
exit(1)
if char == '\n':
count += 1
if count == number + 1:
f.truncate()
print "Removed " + str(number) + " lines from end of file"
exit(0)
f.seek(-1, os.SEEK_CUR)
if count < number + 1:
print "No change: requested removal would leave empty file"
exit(3)
以下是 Python 3 版本:
#!/usr/bin/env python3.0
import os, sys
if len(sys.argv) != 3:
print(sys.argv[0] + ": Invalid number of arguments.")
print ("Usage: " + sys.argv[0] + " linecount filename")
print ("to remove linecount lines from the end of the file")
exit(2)
number = int(sys.argv[1])
file = sys.argv[2]
count = 0
with open(file,'r+b', buffering=0) as f:
f.seek(0, os.SEEK_END)
end = f.tell()
while f.tell() > 0:
f.seek(-1, os.SEEK_CUR)
print(f.tell())
char = f.read(1)
if char != b'\n' and f.tell() == end:
print ("No change: file does not end with a newline")
exit(1)
if char == b'\n':
count += 1
if count == number + 1:
f.truncate()
print ("Removed " + str(number) + " lines from end of file")
exit(0)
f.seek(-1, os.SEEK_CUR)
if count < number + 1:
print("No change: requested removal would leave empty file")
exit(3)
以下是 Python 2.4 版本:
#!/usr/bin/env python2.4
import sys
if len(sys.argv) != 3:
print sys.argv[0] + ": Invalid number of arguments."
print "Usage: " + sys.argv[0] + " linecount filename"
print "to remove linecount lines from the end of the file"
sys.exit(2)
number = int(sys.argv[1])
file = sys.argv[2]
count = 0
SEEK_CUR = 1
SEEK_END = 2
f = open(file,'r+b')
f.seek(0, SEEK_END)
end = f.tell()
while f.tell() > 0:
f.seek(-1, SEEK_CUR)
char = f.read(1)
if char != '\n' and f.tell() == end:
print "No change: file does not end with a newline"
f.close()
sys.exit(1)
if char == '\n':
count += 1
if count == number + 1:
f.truncate()
print "Removed " + str(number) + " lines from end of file"
f.close()
sys.exit(0)
f.seek(-1, SEEK_CUR)
if count < number + 1:
print "No change: requested removal would leave empty file"
f.close()
sys.exit(3)
答案2
你可以尝试 GNU head
head -n -2 file
答案3
我看到我的 Debian Squeeze/测试系统(但不是 Lenny/stable)包含一个“truncate”命令作为“coreutils”包的一部分。
有了它你可以简单地做类似的事情
truncate --size=-160 myfile
从文件末尾删除 160 个字节(显然您需要确定需要删除多少个字符)。
答案4
尝试一下 VIM...我不确定它是否有效,因为我从来没有在这么大的文件上使用过它,但是我过去曾在较小的较大文件上使用过它,尝试一下。