通过regex python解析大文件的最佳方法

时间:2013-08-29 11:33:44

标签: python regex parsing logfile-analysis

我必须在python中使用reg ex解析一个大的日志文件(2GB)。在日志文件中,正则表达式匹配我感兴趣的行。日志文件也可能包含不需要的数据。

以下是文件中的示例:

"#DEBUG:: BFM [L4] 5.4401e+08ps MSG DIR:TX SCB_CB TYPE:DATA_REQ CPortID:'h8 SIZE:'d20 NumSeg:'h0001 Msg_Id:'h00000000"

我的正则表达式为".DEBUG.*MSG."

首先,我将使用空格分割它,然后将“field:value”模式插入到sqlite3数据库中;但对于大文件,解析文件大约需要10到15分钟。

请建议在最短时间内完成上述任务的最佳方式。

3 个答案:

答案 0 :(得分:2)

正如其他人所说,对您的代码进行分析,看看为什么它很慢。 cProfile模块in conjunction with the gprof2dot tool可以生成可读的信息

如果没有看到你的慢代码,我可以猜出一些可能有用的东西:

首先,您可以使用内置字符串方法而不是正则表达式来逃避 - 这可能会稍微快一些。如果你需要使用正则表达式,那么使用re.compile

在主循环之外进行预编译是值得的

其次是不对每行执行一次插入查询,而是批量插入,例如将解析后的信息添加到列表中,然后当它达到一定大小时,使用executemany方法执行一次INSERT查询。

一些不完整的代码,作为上述例子:

import fileinput

parsed_info = []
for linenum, line in enumerate(fileinput.input()):
    if not line.startswith("#DEBUG"):
        continue # Skip line

    msg = line.partition("MSG")[1] # Get everything after MSG
    words = msg.split() # Split on words
    info = {}
    for w in words:
        k, _, v = w.partition(":") # Split each word on first :
        info[k] = v

    parsed_info.append(info)

    if linenum % 10000 == 0: # Or maybe  if len(parsed_info) > 500:
        # Insert everything in parsed_info to database
        ...
        parsed_info = [] # Clear

答案 1 :(得分:0)

“在最短时间内完成上述任务的最佳方式”是首先弄清楚时间的去向。了解如何配置Python脚本以查找哪些部分很慢。你可能有一个低效的正则表达式。写入sqlite可能是个问题。但是没有神奇的子弹 - 一般来说,在Python中使用正则表达式逐行处理2GB的文本可能会在几分钟内运行,而不是几秒钟。

这是一个测试脚本,它将显示逐行读取文件所需的时间,并且不执行任何其他操作:

from datetime import datetime

start = datetime.now()
for line in open("big_honkin_file.dat"):
    pass
end = datetime.now()
print (end-start)

答案 2 :(得分:0)

保罗的回答是有道理的,你需要先了解你“失去”时间的地方。 如果您没有分析器,最简单的方法是在算法的每个“步骤”之前和之后以毫秒为单位发布时间戳(打开文件,逐行读取(内部,分割/正则表达式识别所需的时间)调试行),将其插入数据库等...)。

如果不进一步了解您的代码,可能会非常耗时的“陷阱”: - 多次打开日志文件 - 每次需要在内部插入数据而不是打开一个连接然后随时写入时打开数据库