import re
infile = open('document.txt','r')
outfile= open('output.txt','w')
copy = False
for line in infile:
if line.strip() == "--operation():":
bucket = []
copy = True
elif line.strip() == "StartOperation":
for strings in bucket:
outfile.write( strings + ',')
for strings in bucket:
outfile.write('\n')
copy = False
elif copy:
bucket.append(line.strip()
CSV格式如下:
id, name, poid, error
5896, AutoAuthOSUserSubmit, 900105270, 0x4002
我的日志文件有几个部分,以==== START ====
开头,以==== END ====
结尾。我想在--operation():
和StartOperation
之间提取字符串。例如,AutoAuthOSUserSubmit.
我还想从行poid
中提取poid: 900105270, poidLen: 9
值。最后,我想提取返回值,例如0x4002
如果在Roll back all updates
之后找到它。
如果Start
和End
不在同一行,我甚至无法提取原始文本。我该怎么做呢?
这是一个带有两段的LOG提取示例:
-- 08/24 02:07:56 [mds.ecas(5896) ECAS_CP1] **==== START ====**
open file /ecas/public/onsite-be/config/timer.conf failed
INFO 08/24/16 02:07:56 salt1be-d1-ap(**5896**/0) main.c(780*****):--operation(): AutoAuthOSUserSubmit. StartOperation*****
INFO 08/24/16 02:07:56 salt1be-d1-ap(5896/0) main.c(784):--Client Information: Request from host 'malt-d1-wb' process id 12382.
DEBUG 08/24/16 02:07:56 salt1be-d1-ap(5896/0) TOci.cc(571):FetchServiceObjects: ServiceCert.sql
DEBUG 08/22/16 23:15:53 pepper1be-d1-ap(2680/0) vsserviceagent.cpp(517):Generate Certificate 2: c1cd00d5c3de082360a08730fef9cd1d
DEBUG 08/22/16 23:15:53 pepper1be-d1-ap(2680/0) junk.c(1373):GenerateWebPin : poid: **900105270**, poidLen: 9
DEBUG 08/22/16 23:15:53 pepper1be-d1-ap(2680/0) junk.c(1408):GenerateWebPin : pinStr
DEBUG 08/24/16 02:07:56 salt1be-d1-ap(5896/0) uaadapter_vasco_totp.c(275):UAVascoTOTPImpl.close() -- Releasing Adapter Context
DEBUG 08/22/16 23:15:53 pepper1be-d1-ap(2680/0) vsenterprise.cpp(288):VSEnterprise::Engage returns 0x4002 - Unknown error code **(0x4002)**
ERROR 08/22/16 23:15:53 pepper1be-d1-ap(2680/0) vsautoauth.cpp(696):OSAAEndUserEnroll: error occurred. **Roll back** all updates!
INFO 08/24/16 02:07:56 salt1be-d1-ap(5896/0) uaotptokenstoreqmimpl.cpp(199):Close token store
INFO 08/24/16 02:07:56 salt1be-d1-ap(5896/0) main.c(990):-- EndOperation
-- 08/24 02:07:56 [mds.ecas(5896) ECAS_CP1] **==== END ====**
OPERATION = AutoAuthOSUserSubmit, rc = 0x0 (0)
SYSINFO Elapse = 0.687, Heap = 1334K, Stack = 64K
答案 0 :(得分:1)
看起来您只是想在LOG文档中查找字符串并尝试使用关键字解析字符行。您可以逐行进行当前正在执行的操作,或者您可以浏览一次文档(假设LOG文档永远不会变大)并将每个后续行添加到现有字符串中。
查看此信息以查找子字符串 http://www.tutorialspoint.com/python/string_index.htm< ---用于查找字符串在另一个字符串中的位置,这将帮助您确定起始索引和结束索引。完成后,您可以提取所需信息。
检查此问题是否存在CSV问题 http://www.tutorialspoint.com/python/string_split.htm< ---用于分割特定字符周围的字符串,即“,”,用于CSV文件。
Does Python have a string contains substring method?比使用strip()方法的当前方法更有用
希望这会指出你正确的方向!
答案 1 :(得分:1)
这看起来像正则表达式的工作!实际上有几个。值得庆幸的是,在这种情况下使用起来并不复杂。
有2个主要观察结果会让我选择正则表达式而不是其他东西:
您可以尝试这样的事情:
import re
def capture(text, pattern_string, flags=0):
pattern = re.compile(pattern_string, flags)
match = pattern.search(text)
if match:
output = match.group(1)
print '{}\n'.format(output)
return output
return ''
if __name__ == '__main__':
file = read_my_file()
log_pattern = "\*\*==== START ====\*\*(.+)\*\*==== END ====\*\*"
log_text = capture(file, log_pattern, flags=re.MULTILINE|re.DOTALL)
op_pattern = "--operation\(\): (.+). StartOperation\*\*\*\*\*"
op_name = capture(log_text, op_pattern)
poid_pattern = "poid: \*\*([\d]+)\*\*, poidLen: "
op_name = capture(log_text, poid_pattern)
retcode_pattern = "Unknown error code \*\*\((.+)\)\*\*.+\*\*Roll back\*\* all updates!"
retcode = capture(log_text, retcode_pattern, flags=re.MULTILINE|re.DOTALL)
这种方法基本上将问题分成几个很大程度上独立的步骤。我在每个正则表达式中使用捕获组 - 像(.+)
和([\d]+)
这样的parens - 在长字符串的常量字符之间。 multiline和dotall标志允许您轻松处理文本中的换行符,并像处理字符串的任何其他部分一样处理它们。
我也在这里做了一个很大的假设,那就是你的日志不是大文件,可能是几百兆的顶部。请注意read_my_file()
的调用 - 而不是尝试一次解决这个问题,我选择读取整个文件并在内存中工作。如果文件变得非常大,或者你正在构建一个会获得大量流量的应用程序,这可能是一个坏主意。
希望这有帮助!