我已经阅读了我能找到的所有文章,甚至理解了其中的一些文章,但作为一个 Python 新手,我仍然有点迷茫,希望得到帮助:)
我正在编写一个脚本来从应用程序特定的日志文件中解析感兴趣的项目,每一行都以我可以匹配的时间戳开始,我可以定义两件事来识别我想要捕获的内容,一些部分内容和一个将终止我要提取的内容的字符串。
我的问题是多行的,在大多数情况下,每个日志行都以换行符终止,但某些条目包含 SQL,其中可能有新行,因此会在日志中创建新行。
所以,在一个简单的情况下,我可能有这个:
[8/21/13 11:30:33:557 PDT] 00000488 SystemOut O 21 Aug 2013 11:30:33:557 [WARN] [MXServerUI01] [CID-UIASYNC-17464] BMXAA6720W - USER = (ABCDEF) SPID = (2526) app (ITEM) object (ITEM) : select * from item where ((status != 'OBSOLETE' and itemsetid = 'ITEMSET1') and (exists (select 1 from maximo.invvendor where (exists (select 1 from maximo.companies where (( contains(name,' $AAAA ') > 0 )) and (company=invvendor.manufacturer and orgid=invvendor.orgid))) and (itemnum = item.itemnum and itemsetid = item.itemsetid)))) and (itemtype in (select value from synonymdomain where domainid='ITEMTYPE' and maxvalue = 'ITEM')) order by itemnum asc (execution took 2083 milliseconds)
这一切都显示为一行,我可以与之匹配:
re.compile('\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2}).*(milliseconds)')
但是在某些情况下,SQL 中可能存在换行符,因此我仍想捕获它(并可能用空格替换换行符)。我目前正在一次读取文件一行,这显然是行不通的,所以......
- 我需要一次性处理整个文件吗?它们的大小通常为 20mb。如何读取整个文件并遍历它以查找单行或多行块?
- 我将如何编写一个多行正则表达式来匹配一行上的整个内容或者它分布在多行上?
我的总体目标是对其进行参数化,以便我可以使用它来提取与起始字符串(始终是行的开头)、结束字符串(我想要捕获到的位置)和介于两者之间的值的不同模式匹配的日志条目它们作为标识符。
提前感谢您的帮助!
克里斯。
import sys, getopt, os, re
sourceFolder = 'C:/MaxLogs'
logFileName = sourceFolder + "/Test.log"
lines = []
print "--- START ----"
lineStartsWith = re.compile('\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2})(\ )')
lineContains = re.compile('.*BMXAA6720W.*')
lineEndsWith = re.compile('(?:.*milliseconds.*)')
lines = []
with open(logFileName, 'r') as f:
for line in f:
if lineStartsWith.match(line) and lineContains.match(line):
if lineEndsWith.match(line) :
print 'Full Line Found'
print line
print "- Record Separator -"
else:
print 'Partial Line Found'
print line
print "- Record Separator -"
print "--- DONE ----"
下一步,对于我的部分行,我将继续阅读,直到找到 lineEndsWith 并将这些行组合成一个块。
我不是专家,所以总是欢迎提出建议!
更新 - 所以我让它工作了,感谢所有帮助指导事情的回应,我意识到它并不漂亮,我需要清理我的 if / elif 混乱并使其更有效率,但它正在工作!感谢所有的帮助。
import sys, getopt, os, re
sourceFolder = 'C:/MaxLogs'
logFileName = sourceFolder + "/Test.log"
print "--- START ----"
lineStartsWith = re.compile('\[(0?[1-9]|[12][0-9]|3[01])(\/)(0?[1-9]|[12][0-9]|3[01])(\/)([0-9]{2})(\ )')
lineContains = re.compile('.*BMXAA6720W.*')
lineEndsWith = re.compile('(?:.*milliseconds.*)')
lines = []
multiLine = False
with open(logFileName, 'r') as f:
for line in f:
if lineStartsWith.match(line) and lineContains.match(line) and lineEndsWith.match(line):
lines.append(line.replace("\n", " "))
elif lineStartsWith.match(line) and lineContains.match(line) and not multiLine:
#Found the start of a multi-line entry
multiLineString = line
multiLine = True
elif multiLine and not lineEndsWith.match(line):
multiLineString = multiLineString + line
elif multiLine and lineEndsWith.match(line):
multiLineString = multiLineString + line
multiLineString = multiLineString.replace("\n", " ")
lines.append(multiLineString)
multiLine = False
for line in lines:
print line