廉价方法在大型文本文件中查找字符串

42 投票
9 回答
145470 浏览
提问于 2025-04-16 05:13

我需要在一个比较大的文本文件中查找一个特定的字符串。这个文件是一个构建日志,大约有5000行文字。有什么好的方法可以做到这一点呢?使用正则表达式会有问题吗?我打算先读取一些行,然后用简单的查找方法。

9 个回答

14

下面这个函数可以处理文本文件和二进制文件(不过它返回的是字节位置),它的好处在于可以找到那些跨越行或缓冲区的字符串,而这些字符串在逐行或逐块搜索时可能找不到。

def fnd(fname, s, start=0):
    with open(fname, 'rb') as f:
        fsize = os.path.getsize(fname)
        bsize = 4096
        buffer = None
        if start > 0:
            f.seek(start)
        overlap = len(s) - 1
        while True:
            if (f.tell() >= overlap and f.tell() < fsize):
                f.seek(f.tell() - overlap)
            buffer = f.read(bsize)
            if buffer:
                pos = buffer.find(s)
                if pos >= 0:
                    return f.tell() - (len(buffer) - pos)
            else:
                return -1

这个方法的基本思路是:

  • 先定位到文件中的一个起始位置
  • 从文件中读取数据到缓冲区(要搜索的字符串必须小于缓冲区的大小),但如果不是从头开始,就要回退1个字节,这样可以捕捉到如果字符串在上一个读取的缓冲区的末尾开始,并在下一个缓冲区继续的情况。
  • 返回找到的位置,如果没找到就返回-1

我用类似的方法在更大的ISO9660文件中查找文件的签名,这样做速度很快,而且占用的内存也不多,你还可以使用更大的缓冲区来加快速度。

17

你可以做一个简单的查找:

f = open('file.txt', 'r')
lines = f.read()
answer = lines.find('string')

如果你能只用简单查找的话,那它会比正则表达式快很多。

57

如果文件很大,那么就要按顺序读取每一行,而不是一次性把整个文件都读到内存里:

with open('largeFile', 'r') as inF:
    for line in inF:
        if 'myString' in line:
            # do_something

撰写回答