用Python解析巨大的日志文件

时间:2012-03-08 15:01:29

标签: python parsing text logging

我正在尝试解析一个巨大的日志文件(大约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)

3 个答案:

答案 0 :(得分:12)

替换

for line in FILE.readlines():

for line in FILE:

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

from itertools import islice

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

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

不需要while循环进行if检查即可解决此问题。

答案 1 :(得分: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

答案 2 :(得分:3)

这是一种简单的方法:

with open('logs.txt', 'r') as f:
    for line_number, line in enumerate(f, start=1):
        do_stuff(line)
        if line_number > 500000:
            break