如何在有限环境下用Python删除大文件中的行

6 投票
5 回答
1485 浏览
提问于 2025-04-16 08:40

假设我在美国有一个10GB的硬盘驱动器(HDD)虚拟私人服务器(VPS),而我住在其他地方。我的硬盘上有一个9GB的文本文件。我有512MB的内存,还有差不多同样大小的交换空间。

考虑到我不能增加硬盘空间,也不能把文件移动到其他地方处理,有没有什么有效的方法可以用Python(最好是这样,但其他语言也可以)来删除文件中的某些行呢?

5 个回答

1

更新:

我尝试使用 fileinput 模块的 inplace 功能,创建了一个1GB的文件。我原本期待的结果和实际发生的情况不一样。这次我仔细阅读了文档。

可选的就地过滤:如果在调用 fileinput.input()FileInput 构造函数时传入关键字参数 inplace=1,那么文件会被移动到一个备份文件中,标准输出会被重定向到输入文件(如果已经存在一个与备份文件同名的文件,它会被静默替换)。

来自 docs/fileinput

所以,这似乎现在不是你的选项。请查看其他答案。


编辑前:

如果你想要对文件进行 就地 编辑,可以看看Python的 fileinput 模块 - 文档

我对它在处理10GB文件时的效率并不确定。不过,对我来说,这似乎是你在使用Python时唯一的选择。

2

试试这个:

currentReadPos = 0
removedLinesLength = 0
for line in file:
    currentReadPos = file.tell()
    if remove(line):
        removedLinesLength += len(line)
    else:
        file.seek(file.tell() - removedLinesLength)
        file.write(line + "\n")
        file.flush()
    file.seek(currentReadPos)

我没有实际运行过这个代码,但它的思路是直接在文件里修改,把你想删除的行用你想保留的行覆盖掉。我不太确定在修改文件的时候,如何处理文件的读取和修改之间的关系。

3

这样怎么样?这个方法可以直接在文件中进行编辑。我在一些小的文本文件上测试过(使用的是Python 2.6.1),不过我不太确定在处理大文件时效果如何,因为会有很多跳来跳去的操作,但总的来说……

我用了一个无限循环,并手动检查文件是否到达末尾,因为用 for line in f: 这个写法不太好用(可能是因为跳来跳去的操作搞乱了正常的遍历)。可能还有更好的方法来检查这个,但我对Python还比较陌生,所以如果有更好的方法,请大家告诉我。

另外,你需要定义一个函数 isRequired(line)

writeLoc = 0
readLoc = 0
with open( "filename" , "r+" ) as f:
    while True:
        line = f.readline()

        #manual EOF check; not sure of the correct
        #Python way to do this manually...
        if line == "":
            break

        #save how far we've read
        readLoc = f.tell()

        #if we need this line write it and
        #update the write location
        if isRequired(line):
            f.seek( writeLoc )
            f.write( line )
            writeLoc = f.tell()
            f.seek( readLoc )

    #finally, chop off the rest of file that's no longer needed
    f.truncate( writeLoc )

撰写回答