如何解决Python:解析日志文件中的成对行
我有一个日志文件,需要针对特定事件进行解析。问题是我需要的数据来自成对的事件条目,每个事件条目都包含所需的数据。
例如,将有一行事件类型= test并包含一些数据,然后不久之后又有另一行事件类型= test2并包含一些数据。
文件中这些数据对可能有很多实例,或者没有。
我需要做的是告诉代码,当它找到带有event = test的行时,还要查找event = test2的下一个实例,通常在日志的后面几行。
这是数据文件的示例:
2020-08-25 03:36:56.006 INFO Panda HOOK: {"event":"keepalive","time":1600.0064477}
2020-08-25 03:37:01.006 INFO Panda HOOK: {"event":"keepalive","time":1605.0066958}
2020-08-25 03:37:06.004 INFO Panda HOOK: {"event":"keepalive","time":1610.004206}
2020-08-25 03:37:11.003 INFO Panda HOOK: {"event":"keepalive","time":1615.0032498}
2020-08-25 03:37:16.005 INFO Panda HOOK: {"event":"keepalive","time":1620.0056292}
2020-08-25 03:37:21.001 INFO Panda HOOK: {"event":"keepalive","time":1625.0011002}
2020-08-25 03:37:26.007 INFO Panda HOOK: {"event":"keepalive","time":1630.0073155}
2020-08-25 03:37:31.008 INFO Panda HOOK: {"event":"keepalive","time":1635.0086481}
2020-08-25 03:37:32.687 INFO Scripting: event:type=test,initiator=Abe Lincoln,place=Washinton,2020-08-25 03:37:21.001 INFO Panda HOOK: {"event":"keepalive","time":1635.0086481}
2020-08-25 03:37:34.414 INFO Scripting: event:type=test2,t=25277.04,type=comment,
这是我必须获得第一行2020-08-25 03:37:32.687 INFO Scripting: event:type=test,
f = open('data.log','r')
lines = f.readlines()
test2Event = 'event:type=test2'
testEvent = 'event:type=test'
for string in lines:
if testEvent in string:
initPerson = string.split('initiator=')[1]
f = open('data.log','r')
lines = f.readlines()
test2Event = 'event:type=test2'
testEvent = 'event:type=test'
for string in lines:
if testEvent in string:
initPerson = string.split('initiator=')[1]
person = initPerson.split(',')[0]
print(person)
到目前为止,我在使用此代码以及所需的结果时遇到错误。我不明白为什么,因为我使用了这个完全相同的脚本,并使用了不同的字符串来进行拆分,而没有任何问题。
结果
Abe Lincoln
Traceback (most recent call last):
File "main.py",line 15,in <module>
initPerson = string.split('initiator=')[1]
IndexError: list index out of range
任何有关如何获取下一行数据的建议,以便我可以将数据合并到db或类似数据库中,以及对为什么出现错误消息的任何帮助都将受到赞赏,因为我没有看看问题出在哪里。
代码和数据可在https://onlinegdb.com/Hyuuj7Mmv进行测试
解决方法
两次读取整个文件绝对是多余的。相反,请在遍历文件时跟踪以前所做的事情。
seen_test = False # state variable for keeping track of what you have done
init_person = None # note snake_case variable convention pro headlessCamelCase
with open('data.log','r') as f:
for lineno,line in enumerate(f,start=1):
if 'event:type=test,' in line:
if seen_test:
raise ValueError(
'line %i: type=test without test2: %s' % (
lineno,line))
init_person = line.split('initiator=')[1].split(',')[0]
seen_test = True
elif 'event:type=test2' in line:
if seen_test:
# ... do whatever you want with init_person
# maybe something like
result = line.rstrip('\n').split(',')
print('Test by %s got results %s' % (init_person,result[1:]))
else:
raise ValueError(
'line %i: type=test2 without test: %s' % (
lineno,line))
seen_test = False
enumerate
只是为了在发生故障时在错误消息中添加有用的行号;如果您确定文件始终格式正确,则可以将其删除。
如果type=test
行中不包含initiator=
,这仍然会失败,但是我们不知道在这种情况下有什么用处,所以我不会尝试解决。
演示:https://repl.it/repls/OverdueFruitfulComputergames#main.py
,这应该做您想要的:
import re
f = open('data.log','r')
lines = f.readlines()
results = {}
for line in lines:
if "Scripting:" in line.strip():
res = dict(re.findall(r"([^= ]+)=(.+?),",line.strip(),re.DOTALL))
# if the eventtype ends with `2` and match an existing key in results,update data
if res['event:type'][-1] == '2' and res['event:type'][:-1] in results:
results[res['event:type'][:-1]].update(res)
else:
results[res['event:type']] = res
print(results)
# {'test': {'event:type': 'test2','initiator': 'Abe Lincoln','place': 'Washinton','t': '25277.04','type': 'comment'}}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。