如何遍历由分号分隔的超大文本文件?

时间:2018-10-12 01:31:48

标签: python file-processing python-textprocessing

如果我想逐行遍历文本文件,请按以下步骤操作:

for curr_line in open('my_file.txt', 'r').readlines()
    print '|' + curr_line + '|'

如果我想遍历基于分号分隔符的文本,请按以下步骤操作:

for curr_line in open('my_file.txt', 'r').read().split(';')
    print '|' + curr_line + '|'

如果我要逐行遍历非常大的文本文件,请按以下步骤操作:

for curr_line in open('my_file.txt', 'r').xreadlines()
    print '|' + curr_line + '|'

但是我如何遍历基于分号的超大文本文件呢?它是7+ GB,因此我无法将整个内容读到内存中。

下面是示例输入文件my_file.txt

AAAA;BBBBB
BB;CCC;
DDDDD
D
D;
EEEE;F

这是我想根据上面的片段看到的输出:

|AAAA|
|BBBBB
BB|
|CCC|
|DDDDD
D
D|
|EEEE|
|F|

2 个答案:

答案 0 :(得分:1)

方法.readlines()将整个文件读取到一个列表中。对于7GB的文件,这可能不可行。

鉴于添加的示例,您可以使用mmap和一个正则表达式来进行整个文件的正则表达式匹配,而无需加载整个文件:

import re 
import mmap 

with open(fn,'r+b') as f_in:
    mm = mmap.mmap(f_in.fileno(), 0)    
    for m in re.finditer('([^;]*)', mm):
        txt=m.group(1)
        if txt:
            print('|{}|'.format(txt))

在示例中,打印:

|AAAA|
|BBBBB
BB|
|CCC|
|
DDDDD
D
D|
|
EEEE|
|F|

答案 1 :(得分:1)

这是一个“读取器”对象,该对象将从文件中读取块(具有您选择的大小),并在找到它们时发出以分号分隔的项目:

class MyReader:
    def __init__(self, handle, delim, read_size=512):
        self.handle = handle
        self.delim = delim
        self.read_size = read_size


    def __iter__(self):
        buffer = []
        while True:
            block = self.handle.read(self.read_size)
            if not block: break     # Reached EOF

            while block:
                (before, sep, block) = block.partition(self.delim)
                buffer.append(before)

                if sep:             # Separator was found, yield the buffer
                    yield ''.join(buffer)
                    buffer = []

        # We broke free, flush the buffer and return (explicit)
        yield ''.join(buffer)
        return

例如,您可能会使用以下哪一种:

with open('file.txt') as f:
    reader = MyReader(f, ';')

    for chunk in reader:
        print(repr(chunk))

输出:

'AAAA'
'BBBBB\nBB'
'CCC'
'\nDDDDD\nD\nD'
'\nEEEE'
'F'