在适合两种格式的文本文件中查找所有字符串
Find all strings in text file fitting either of two formats
所以我知道以前也有人问过类似的问题,但是我试过的每一种方法都不行...
这是一个问题:我有一个文本文件(它是一个日志文件),我正在分析它是否出现任何“app.task2”。以下是可能发生的 2 种情况(它们出现在文本文件中,与我的代码无关):
场景 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
如何获取第一种情况的完整日志条目?我尝试剥离转义字符,但没有成功。从这里我应该能够解析返回的结果列表以获得我真正需要的结果,但这会有所帮助!泰!
注意:我需要能够通过字符串“app.task2”找到这些类型的日志条目(然后将为我们提供场景 1 或场景 2)。所以这需要合并,就像我的例子一样......
在将行添加到 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')
所以我知道以前也有人问过类似的问题,但是我试过的每一种方法都不行...
这是一个问题:我有一个文本文件(它是一个日志文件),我正在分析它是否出现任何“app.task2”。以下是可能发生的 2 种情况(它们出现在文本文件中,与我的代码无关):
场景 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
如何获取第一种情况的完整日志条目?我尝试剥离转义字符,但没有成功。从这里我应该能够解析返回的结果列表以获得我真正需要的结果,但这会有所帮助!泰!
注意:我需要能够通过字符串“app.task2”找到这些类型的日志条目(然后将为我们提供场景 1 或场景 2)。所以这需要合并,就像我的例子一样......
在将行添加到 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')