将制表符分隔的日志行优雅地转换为 CSV 矩阵
Elegant conversion of tab separated log lines into a CSV matrix
我有一个制表符分隔的日志文件,其中包含如下行:
event_a info1 info2
event_b info1 info4
event_c info2 info5 ...
我想将其转换为 csv(具有 Python),其中一列具有含义。信息 1 例如是ID,info2是目的地,info4是坐标等等
我可以通过 "sloppy" 的方式轻松做到这一点:
if "event_a" in line:
columns = line.split()
id = columns[1]
我更愿意为此使用查找矩阵或 table 结构,以便列的位置与编程逻辑分开。有没有什么东西可以让我在这里定义一个富有表现力的概述,这样我就可以像这样编码:
for line in csvfile:
matches = event_table.match(line)
for match in matches:
event_table.convert(match)
# add commas in between the values to account for empty columns
我当然可以为每个事件创建一个 class,但这似乎有些矫枉过正。我正在寻找的是一个中心定义,我可以使用它。
输出为:
event_a, info1 info2
event_b, info1, , , info4
event_b, , info2, , , info5
...
event_365, , , , , , , , , , , , info12
编辑:日志文件包含 100 种此类事件类型,这会使这段代码相当长且难以维护 "waterfall"-解析方式
听起来您可以先拆分行,然后使用单元格[0] 访问查找table
这是一种方法,虽然我觉得我在玩代码高尔夫。
lines = ['fooevent\tfoo_info1\tfoo_info2',
'barevent\tbar_info2\tbar_info4',
'basevent\tbas_info2\tbas_info5'
]
mapper = {
'fooevent':(1,2),
'barevent':(2,4),
'basevent':(2,5)
}
output_length = max([max(v) for v in mapper.values()]) + 1
a = lambda x,m: fields[1:][m.index(x)] if x in m else ''
for line in lines:
fields = line.split('\t')
data = [a(x,mapper[fields[0]]) for x in range(1,output_length)]
data.insert(0,fields[0])
print(','.join(data))
对于单个映射器使用散列可能比元组更容易,如果只是因为如果您的映射 table 变得更复杂,它们以后更容易映射到其他数据类型。
我有一个制表符分隔的日志文件,其中包含如下行:
event_a info1 info2
event_b info1 info4
event_c info2 info5 ...
我想将其转换为 csv(具有 Python),其中一列具有含义。信息 1 例如是ID,info2是目的地,info4是坐标等等
我可以通过 "sloppy" 的方式轻松做到这一点:
if "event_a" in line:
columns = line.split()
id = columns[1]
我更愿意为此使用查找矩阵或 table 结构,以便列的位置与编程逻辑分开。有没有什么东西可以让我在这里定义一个富有表现力的概述,这样我就可以像这样编码:
for line in csvfile:
matches = event_table.match(line)
for match in matches:
event_table.convert(match)
# add commas in between the values to account for empty columns
我当然可以为每个事件创建一个 class,但这似乎有些矫枉过正。我正在寻找的是一个中心定义,我可以使用它。
输出为:
event_a, info1 info2
event_b, info1, , , info4
event_b, , info2, , , info5
...
event_365, , , , , , , , , , , , info12
编辑:日志文件包含 100 种此类事件类型,这会使这段代码相当长且难以维护 "waterfall"-解析方式
听起来您可以先拆分行,然后使用单元格[0] 访问查找table
这是一种方法,虽然我觉得我在玩代码高尔夫。
lines = ['fooevent\tfoo_info1\tfoo_info2',
'barevent\tbar_info2\tbar_info4',
'basevent\tbas_info2\tbas_info5'
]
mapper = {
'fooevent':(1,2),
'barevent':(2,4),
'basevent':(2,5)
}
output_length = max([max(v) for v in mapper.values()]) + 1
a = lambda x,m: fields[1:][m.index(x)] if x in m else ''
for line in lines:
fields = line.split('\t')
data = [a(x,mapper[fields[0]]) for x in range(1,output_length)]
data.insert(0,fields[0])
print(','.join(data))
对于单个映射器使用散列可能比元组更容易,如果只是因为如果您的映射 table 变得更复杂,它们以后更容易映射到其他数据类型。