(Python)尽可能快地计算巨大(> 10GB)文件中的行

Adr*_*nne 22 python enumerate line-count

我现在有一个非常简单的脚本,它使用以下方法计算文本文件中的行enumerate():

i = 0
f = open("C:/Users/guest/Desktop/file.log", "r")
for i, line in enumerate(f):
      pass
print i + 1
f.close()
Run Code Online (Sandbox Code Playgroud)

这需要大约3分半钟才能完成大约3000万行的15GB日志文件.如果我能在两分钟或更短的时间内得到它,那将是很好的,因为这些是每日日志,我们想要进行每月分析,因此代码必须处理30个~15GB的日志 - 可能超过一个半小时,我们希望尽量减少服务器上的时间和内存负载.

我也会接受一个很好的近似/估计方法,但它需要大约4 sig fig准确...

谢谢!

glg*_*lgl 26

Ignacio的答案是正确的,但如果你有32位进程可能会失败.

但也许以块为单位读取文件然后计算\n每个块中的字符可能是有用的.

def blocks(files, size=65536):
    while True:
        b = files.read(size)
        if not b: break
        yield b

with open("file", "r") as f:
    print sum(bl.count("\n") for bl in blocks(f))
Run Code Online (Sandbox Code Playgroud)

会做你的工作.

请注意,我不打开文件作为二进制文件,因此\r\n将转换为\n,使计数更可靠.

对于Python 3,并使其更健壮,用于读取具有各种字符的文件:

def blocks(files, size=65536):
    while True:
        b = files.read(size)
        if not b: break
        yield b

with open("file", "r",encoding="utf-8",errors='ignore') as f:
    print (sum(bl.count("\n") for bl in blocks(f)))
Run Code Online (Sandbox Code Playgroud)

  • @MKatz现在是什么,"大文件"或"大约51 MB的文件"?;-) (4认同)
  • 不是人们关心定义。当你处理真实数据时,一切都是乱七八糟的。但无论如何都无所谓。 (2认同)

Jak*_*yer 9

我知道它有点不公平,但你可以做到这一点

int(subprocess.check_output("wc -l C:\\alarm.bat").split()[0])
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Windows,请查看Coreutils.

  • 似乎你需要为python3做`int(subprocess.check_output("/usr/bin/wc -l cred", shell=True).split()[0])` (3认同)

AJS*_*yth 7

一种快速的一线解决方案是:

sum(1 for i in open(file_path, 'rb'))
Run Code Online (Sandbox Code Playgroud)

它应该适用于任意大小的文件。

  • 文件未关闭。 (3认同)

Ign*_*ams 5

mmap文件,并计算换行符。

import mmap

def mapcount(filename):
    with open(filename, "r+") as f:
        buf = mmap.mmap(f.fileno(), 0)
        lines = 0
        readline = buf.readline
        while readline():
            lines += 1
        return lines
Run Code Online (Sandbox Code Playgroud)

  • 请考虑添加一个简短的示例来演示这一点,谢谢! (10认同)
  • 简短的例子可能是个好主意,我同意 (5认同)