所以我知道以前也问过类似的问题,但我尝试过的每一种方法都不起作用。。。
这是一个问题:我有一个文本文件(它是一个日志文件(,我正在解析它;app.task2";。以下是可能发生的两种情况(它们出现在文本文件中,与我的代码无关(:
场景1:
Mar 23 10:28:24 dasd[116] <Notice>: app.task2.refresh:556A2D:[
{name: ApplicationPolicy, policyWeight: 50.000, response: {Decision: Can Proceed, Score: 0.45}}
] sumScores:68.785000, denominator:96.410000, FinalDecision: Can Proceed FinalScore: 0.713463}
场景2:
Mar 23 10:35:56 dasd[116] <Notice>: 'app.task2.refresh:C6C2FE' CurrentScore: 0.636967, ThresholdScore: 0.410015 DecisionToRun:1
我面临的问题是,我在下面的当前代码中,我没有获得第一种情况的整个日志条目,它只是拉日志中的第一行,而不是日志条目的其余部分,并且它似乎停止在新行转义符处,该转义符发生在":[〃.
我的代码:
all = []
with open(path_to_log) as f:
for line in f:
if "app.task2" in line:
all.append(line)
print all
如何获取第一种情况的整个日志条目?我试着剥去逃跑的角色,但没有成功。从这里开始,我应该能够解析返回的结果列表,以获得我真正需要的结果,但这将有所帮助!ty!
注意:我需要能够通过字符串"来定位这些类型的日志条目(这将给出场景1或场景2(;app.task2";。所以这需要被纳入,就像在我的例子中
在将行添加到all
之前,请检查它是否以[
结尾。如果是,继续阅读并合并行,直到到达]
。
import re
all = []
with open(path_to_log) as f:
for line in f:
if "app.task2" in line:
if re.search(r'[s*$', line): # start of multiline log message
for line2 in f:
line += line2
if re.search(r'^s*]', line2): # end of multiline log message
break
all.append(line)
print(all)
您正在逐个迭代每一行,这就是为什么在场景1中只得到第一行。
要么你可以添加这样的计数器:
all = []
count = -1
with open(path_to_log) as f:
for line in f:
if count > 0:
all.append(line)
if count == 1:
tmp = all[-count:]
del all[-count:]
all.append("n".join(tmp))
count -= 1
continue
if "app.task2" in line:
all.append(line)
if line.endswith('[n'):
count = 3
print all
在这种情况下,我认为Barmar解决方案也同样有效。
或者,在存储日志文件时,您可以(最好(在每个日志条目之间有一些不同的分隔符,并通过该分隔符分割日志文件。
我喜欢@Barmar在同一文件对象上嵌套循环的解决方案,将来可能会使用这种技术。但在看到之前,我会用一个循环来完成它,它可能更可读,也可能不可读:
all = []
keep = False
for line in open(path_to_log,"rt"):
if "app.task2" in line:
all.append(line)
keep = line.rstrip().endswith("[")
elif keep:
all.append(line)
keep = not line.lstrip().startswith("]")
print (all)
或者,你可以用打印得更好
print(*all,sep='n')