Python 解析文件
我想知道在以下情况下最好的处理方法是什么。
假设我们有一个很大的文件,这个文件记录了编译的输出,还有一些错误模式我想用来检查这个文件,比如错误模式可能是:
- : error:
- : error [A-Z]*[\d ]*
- [A-Z]*[\d]* [E\e|rror:
- " Cannot open include file "
- " Could not find "
- "is not a member of"
- "has not been declared"
请告诉我这样做是否高效:
- 把文件的内容放到一个变量里,然后关闭文件
- 用grep命令查找列表中的每个错误
- 或者为每个错误创建正则表达式,然后在变量中解析
谢谢!
3 个回答
0
这样做其实效率不高,因为你要把大量的数据都读到内存里,然后再进行操作。如果你的内存不够大,这样做可能就不太合适了。
不如用生成器来处理:
def parser(filename):
with open(filename, 'r') as f: # For use in python > 2.4 I *think*.
for line in f:
if anymatches(line): # or whatever you want to do to generate a
yield line # true/false value
这样做的好处是不会把整个文件都加载到内存中,而且只会在你需要的时候才生成匹配的结果。所以如果你只想要前面 N
个匹配结果,可以这样做:
for i, match in zip(xrange(N), parser('mylogfile')):
#do something with match
0
因为日志文件很大,所以检查错误的更有效的方法是逐行读取文件,检查每一行是否符合你的模式。你不想把一个巨大的文件不必要地放在内存里。
在Python中,可能可以这样做:
err = re.compile(': error(?::| [A-Z]*[\d ]*)|[A-Z]*\d* [Ee]rror:|' +
'" (?:Cannot open include file|Could not find) "|' +
'"(?:is not a member of|has not been declared)"')
with open('file.log') as f:
for line in f:
m = err.search(line)
if m is not None:
# this line indicates an error
不过你可能需要根据自己的需求调整正则表达式。另一种方法是准备一个静态字符串的列表,比如:
err_list = ['error', 'Cannot open include file', 'Could not find', 'is not a member of', 'has not been declared']
然后在每一行中搜索这些字符串:
with open('file.log') as f:
for line in f:
if any(line.find(e) for e in err_list):
# this line indicates an error
2
如果日志文件很大,把它全部加载到内存里可能不是个好主意。相反,你可以先把所有的正则表达式预先编译好,然后逐行进行测试,比如:
def has_error(filename):
with file(filename, 'r') as logfile:
for line in logfile:
for regexp in MY_REGEXPS:
if regexp.search(line):
return True
return False