在Python中从大文件中删除行的最快方法

26 投票
9 回答
18075 浏览
提问于 2025-04-15 19:41

我正在Linux系统上处理一个非常大的文本文件,差不多有11GB。现在我在用一个程序检查这个文件有没有错误。一旦发现错误,我需要修复那一行或者干脆把它删掉。然后再重复这个过程……

等我对这个过程熟悉了,我会把它完全自动化。不过现在,假设我还是手动来做这件事。

那么,最快的方式(从执行时间上来说)来删除这个大文件中的某一行是什么呢?我想过用Python来做……但也愿意看看其他的例子。那一行可能在文件的任何地方

如果用Python,假设接口是这样的:

def removeLine(filename, lineno):

谢谢,

-aj

9 个回答

1

据我所知,你不能直接用Python打开一个txt文件然后删除某一行。你需要新建一个文件,把除了那一行以外的所有内容都移动到新文件里。如果你知道具体要删除的那一行,你可以这样做:

f = open('in.txt')
fo = open('out.txt','w')

ind = 1
for line in f:
    if ind != linenumtoremove:
        fo.write(line)
    ind += 1

f.close()
fo.close()

当然,你也可以先检查那一行的内容,看看是否想要保留它。我还建议,如果你有一整串要删除或修改的行,最好一次性处理完,这样效率更高。

8

直接在文件中进行修改,也就是说,把出问题的那一行用空格替换掉,这样文件的其他部分就不需要在磁盘上移动了。如果修复的内容不超过原来那一行的长度,你也可以直接在原地“修复”这一行。

import os
from mmap import mmap
def removeLine(filename, lineno):
    f=os.open(filename, os.O_RDWR)
    m=mmap(f,0)
    p=0
    for i in range(lineno-1):
        p=m.find('\n',p)+1
    q=m.find('\n',p)
    m[p:q] = ' '*(q-p)
    os.close(f)

如果另一个程序可以改成输出文件的偏移量,而不是行号,那你就可以直接把偏移量赋值给p,这样就不需要用到for循环了。

15

你可以同时对同一个文件有两个文件对象,一个用来读取,另一个用来写入:

def removeLine(filename, lineno):
    fro = open(filename, "rb")

    current_line = 0
    while current_line < lineno:
        fro.readline()
        current_line += 1

    seekpoint = fro.tell()
    frw = open(filename, "r+b")
    frw.seek(seekpoint, 0)

    # read the line we want to discard
    fro.readline()

    # now move the rest of the lines in the file 
    # one line back 
    chars = fro.readline()
    while chars:
        frw.writelines(chars)
        chars = fro.readline()

    fro.close()
    frw.truncate()
    frw.close()

撰写回答