在无法容纳内存的大文件中查找出现的字符串

Posted

技术标签:

【中文标题】在无法容纳内存的大文件中查找出现的字符串【英文标题】:find occurrences of a string in a large file that cannot fit memory 【发布时间】:2013-07-23 05:21:07 【问题描述】:

我被要求在一个 10GB 大且有 1GB RAM 的大文件中查找字符串“And”的出现次数。我将如何有效地做到这一点。我回答说我们需要在每个 100MB 的内存块中读取文件,然后找到每个内存块中“And”的总出现次数,并保持字符串“And”的累积计数。面试官对我的回答不满意,他告诉我 grep 命令在 unix 中是如何工作的。在 python 中编写类似的代码,但我不知道答案。我会很感激回答这个问题。

【问题讨论】:

This 可能会有所帮助。 如果不是逐行阅读,别忘了检查边界 【参考方案1】:

遍历文件,返回行。在这种情况下很容易,因为搜索字符串不包含行尾字符,所以我们不需要担心匹配跨行。

with open("file.txt") as fin:
    print sum(line.count('And') for line in fin)

在每一行使用str.count

>>> 帮助(str.count) 关于method_descriptor的帮助: 数数(...) S.count(sub[, start[, end]]) -> int 返回子字符串 sub in 的非重叠出现次数 字符串 S[开始:结束]。可选参数 start 和 end 被解释 与切片表示法一样。

【讨论】:

【参考方案2】:

如果您使用generators,您可以访问一个大文件并进行处理。

简单的grep命令,

def command(f):
    def g(filenames, **kwa):
        lines = readfiles(filenames)
        lines = (outline for line in lines for outline in f(line, **kwa))
        # lines = (line for line in lines if line is not None)
        printlines(lines)
    return g

def readfiles(filenames):
    for f in filenames:
        for line in open(f):
            yield line


def printlines(lines):
    for line in lines:
            print line.strip("\n")

@command
def grep(line, pattern):
    if pattern in line:
        yield line


if __name__ == '__main__':
    import sys
    pattern = sys.argv[1]
    filenames = sys.argv[2:]
    grep(filenames, pattern=pattern)

【讨论】:

以上是关于在无法容纳内存的大文件中查找出现的字符串的主要内容,如果未能解决你的问题,请参考以下文章

字符串查找(重复次数)

java中什么样的对象能够进入老年代

如何在二进制文件中查找 ANSI 字符串?

在Android Studio中搜索整个项目中所有出现的字符串

C# 在表示字符串的大字节数组中寻找子数组

查找文件中出现的字符串并通过批处理文件显示“文件名 - 计数”