(Python) 解析文件以避免性能问题的最佳方法
我对处理一个需要隔离信息的文件的最佳方法有些担心。
举个例子,想象一下一个日志文件,它的数据是分成多个块的,每个块里又有一些子块。
日志文件的例子:
data
data
data
data
block 1 start
-sub block 1 start
--data x
--data y
-sub block 1 end
-sub block 2 start
--data x
--data marked as good
--data z
-sub block 2 end
block 1 end
block 1 summary
block 2 start
-sub block 1 start
.....
-sub block 1 end
....
data
data
data
我在寻找一种高效的方法来解析这个比较大的文件(里面有好几兆的文本),隔离出这些块,然后在每个块里检查特定的子块是否有某一行。如果这一行在子块里,我会保存这个块的开始和结束行,以及包含这一行的子块(但会丢弃那些没有数据的其他子块)。一直做到文件结束。
结果应该是这样的:
block 1 start
-sub block 2 start
--data marked as good
-sub block 2 end
block 1 summary
.....
目前我使用的方法是:我打开文件,然后把文件分成更小的部分来处理;我有三个列表来收集信息。
第一个列表叫做 List_general,它会包含整个日志文件解析的结果,去掉那些与我需要隔离的块无关的内容。基本上在这一步之后,我只会留下像上面例子中的块,去掉“数据”行。在这个过程中,我会检查“好数据”这个字符串,如果我至少看到一次这个字符串,就说明有我需要处理和保存的数据,否则我就结束这个函数。
如果有数据需要处理,我会逐行查看 List_general,开始隔离每个块和子块。从第一个块开始(也就是从块1的开始到块1的总结,如果你看例子的话)。
一旦我到达一个块的结束(块1总结);如果有标记为好的数据,我就会开始解析,逐个查看每个子块,找出哪个子块有好的数据。
我会逐行复制每个子块的内容,就像我处理块一样(基本上是从“子块1开始”到“子块1结束”逐行复制),并检查这个子块里是否有好的数据。如果有,我就把内容复制到最终列表中,否则我就删除这个列表,开始下一个子块。
我知道这种逐个解析每个部分的方法非常繁琐,而且资源消耗也很大;所以我在想有没有“更好”的方法来做到这一点。我对Python还很陌生,所以不太确定如何处理类似的问题。希望这里有人遇到过类似的问题,可以给我建议一下最佳的解决方案。
2 个回答
如果你能通过 block ... start
和 block ... end
来识别出区块或子区块的开始和结束,那么你就可以在阅读的过程中处理每个区块,并把结果存储到你需要的地方。
对于日志文件,我会在解析文件时丢掉那些我不关心的行,把有用的信息存储到sqlite里(可以看看sqlite3这个模块)。然后等我解析完文件后再进行报告和处理。
Sqlite可以设置为使用硬盘或内存来存储数据,所以你可以根据自己的需要来选择。
我喜欢这种方法,因为它很灵活,而且我不需要解析任何内容两次。
补充:这和这个类似吗?
class Parser:
def __init__(self, logfile):
self.log = open(logfile)
self.logentry = []
def next(self):
found = False
for line in self.log:
self.logentry.append(line)
if <block ends>:
e = '\n'.join(self.logentry)
self.logentry = []
yield e