用Python解析巨大的日志文件

Spe*_*cer 1 python logging parsing text

我试图解析一个巨大的日志文件(约5 GB).

我只想解析前500,000行,我不想将整个文件读入内存.

基本上,我想做以下代码正在做的事情,但是使用while循环而不是for循环和if条件.我还想确保不要将整个文件读入内存.

import re
from collections import defaultdict
FILE = open('logs.txt', 'r')
count_words=defaultdict(int)
import pickle
i=0
for line in FILE.readlines():
    if i < 500000:
        m = re.search('key=([^&]*)', line)
        count_words[m.group(1)]+=1
    i+=1

csv=[]
for k, v in count_words.iteritems():
    csv.append(k+","+str(v))
print "\n".join(csv)
Run Code Online (Sandbox Code Playgroud)

Fre*_*Foo 12

更换

for line in FILE.readlines():
Run Code Online (Sandbox Code Playgroud)

for line in FILE:
Run Code Online (Sandbox Code Playgroud)

避免将其全部读入内存.然后,要仅处理前500000行,请执行

from itertools import islice

for line in islice(FILE, 500000):
    m = re.search('key=([^&]*)', line)
    count_words[m.group(1)] += 1
Run Code Online (Sandbox Code Playgroud)

这样你只需要加载你正在使用的文件的前缀.(您当前的程序实际上将遍历整个文件,无论是否将其完全加载到内存中.)

不需要while带有if检查的循环来解决这个问题.


Edw*_*win 5

调用readlines()会将整个文件调用到内存中,因此您必须逐行读取,直到达到500,000行或按EOF(以先到者为准).这是你应该做的事情:

i = 0
while i < 500000:
    line = FILE.readline()
    if line == "": # Cuts off if end of file reached
        break
    m = re.search('key=([^&]*)', line)
    count_words[m.group(1)]+=1
    i += 1
Run Code Online (Sandbox Code Playgroud)