gpt4 book ai didi

python - 解析文本日志文件以从日志消息中提取一些数据字段

转载 作者:太空宇宙 更新时间:2023-11-04 01:35:40 25 4
gpt4 key购买 nike

我是 python 的新手,一直不知道如何去做。我有一个大约 4GB 的非常大的文本文件包含错误消息。文本文件中的每个消息行代表一条消息,我需要过滤掉几列并将空格字符替换为 |。示例:

input:
83b14af0-949b-71e0-18d5-0ad781020000 40ba8352-8dd2-71dc-12b8-0ad781020000 1 -1407714483 20 COLG-GRA-617-RD1.oss 1 181895426 12 oss-ap-1.oss 0 0 48 0 0 0 1307845644 1307845647 0 2 12 0 0 0 0 0 12 0 0 0 0 0 1307845918 3 OpC 6 opcecm 9 SNMPTraps 8 IBB_COLG 4 ATM0 0 0 0 69 Cisco Agent Interface Up (linkUp Trap) on interface ATM0 --Sev Normal 372 Generic: 3; Specific: 0; Enterprise: .1.3.6.1.4.1.9.1.569;
output:
83b14af0-949b-71e0-18d5-0ad781020000 | 40ba8352-8dd2-71dc-12b8-0ad781020000 | COLG-GRA-617-RD1.oss | 1307845644 | 1307845647 |1307845918 | Cisco Agent Interface Up (linkUp Trap) on interface ATM0 | Normal 372 | Generic: 3 | Specific: 0 | Enterprise: .1.3.6.1.4.1.9.1.569

非常感谢任何帮助

谢谢

最佳答案

您的输入文件格式很烦人。我们可以在空格上拆分输入,但您要捕获的某些字段应该包含空格。我们可以按列号拆分输入,但我不确定每个字符串的长度是否始终相同;这些数字的位数似乎可能会有所不同。所以最好的解决方案应该涉及正则表达式。

用一个正则表达式来解析整行代码,写起来和理解起来都会让人头疼。但是我们可以从较短的模式中构建模式。我认为结果很容易理解。此外,如果文件格式发生变化或您要捕获的字段发生变化,我认为您可以很容易地进行更改。

请注意,我们使用 Python 的“字符串重复”运算符 * 来重复较短的模式。如果我们有 2 个词要识别和捕获,我们可以使用 c*2 重复捕获模式两次。

在您的所需输出示例中,您有一些额外的空白。我写的模式不捕获任何空白,但如果您真的想要空白,您可以根据需要编辑模式。

如果您不了解正则表达式,您应该阅读 Python re 模块的文档。简而言之,模式中括号内的部分将被捕获,其他部分将匹配但不被捕获。 \s 匹配空白,\S 匹配非空白。模式中的 + 表示“1 个或多个”,* 表示“0 个或多个”。 ^$ 分别匹配模式的开头和结尾。

import re

# Define patterns we want to recognize.

c = r'(\S+)\s+' # a word we want to capture
s = r'\S+\s+' # a word we want to skip
mesg = r'(\S.*\S)\s+--Sev\s+' # mesg to capture; terminated by string '--Sev'
w2 = r'(\S+\s+\S+)\s+' # two words separated by some white space
w2semi = r'(\S+\s+\S+)\s*;\s+' # two words terminated by a semicolon
tail = r'(.*\S)\s*;'

# Join together the above patterns to make one giant pattern that parses
# the input.
s_pat = ( r'^\s*' +
c*2 + s*3 + c*1 + s*10 + c*2 + s*14 + c*1 + s*14 +
mesg + w2 + w2semi*2 + tail +
r'\s*$')

# Pre-compile the pattern for speed.
pat = re.compile(s_pat)

# Test string and the expected output result.
s_input = "83b14af0-949b-71e0-18d5-0ad781020000 40ba8352-8dd2-71dc-12b8-0ad781020000 1 -1407714483 20 COLG-GRA-617-RD1.oss 1 181895426 12 oss-ap-1.oss 0 0 48 0 0 0 1307845644 1307845647 0 2 12 0 0 0 0 0 12 0 0 0 0 0 1307845918 3 OpC 6 opcecm 9 SNMPTraps 8 IBB_COLG 4 ATM0 0 0 0 69 Cisco Agent Interface Up (linkUp Trap) on interface ATM0 --Sev Normal 372 Generic: 3; Specific: 0; Enterprise: .1.3.6.1.4.1.9.1.569;"
s_correct = "83b14af0-949b-71e0-18d5-0ad781020000|40ba8352-8dd2-71dc-12b8-0ad781020000|COLG-GRA-617-RD1.oss|1307845644|1307845647|1307845918|Cisco Agent Interface Up (linkUp Trap) on interface ATM0|Normal 372|Generic: 3|Specific: 0|Enterprise: .1.3.6.1.4.1.9.1.569"

# re.match() returns a "match group"
m = re.match(pat, s_input)
# m.groups() returns sequence of captured strings; join with '|'
s_output = '|'.join(m.groups())

# sanity check
if s_correct == s_output:
print "excellent"
else:
print "bogus"

# excellent.

通过编写、测试和 Debug模式,编写实际处理文件的程序非常简单。

# use the pattern defined above, named "pat"
with open(input_file, "r") as f_in, open(output_file, "w") as f_out:
for line_num, line in enumerate(f_in, 1):
try:
m = re.match(pat, line)
s_output = '|'.join(m.groups())
f_out.write(s_output + '\n')
except Exception:
print("unable to parse line %d: %s" % (line_num, line)

这将一次读取文件一行,处理该行,并将处理后的行写入输出文件。

请注意,我在一行中使用了多个 with 语句。这适用于任何最新的 Python,但不适用于 2.5 或 3.0。

关于python - 解析文本日志文件以从日志消息中提取一些数据字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10069689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com