首页 > 解决方案 > 解析文本文件并格式化为 CSV

问题描述

所以在我发布这个问题之前,我发现了一个与我的问题相似但不准确的问题。 如何将此文本文件格式解析为 CSV 格式?

我有一个需要解析的文本文件。

票号:2423
旧源 IPIP:1.1.1.1
旧源端口:50
主机 IP:2.2.2.2
主机端口:52漏洞利用
:SomeRANDOMexploit
一堆随机电子邮件标题垃圾票
号:2423
旧源 IPIP:1.1.1.1
旧源端口: 50
主机 IP:2.2.2.2
主机端口:52
漏洞利用:SomeRANDOMexploit

我想解析出所有“一堆随机电子邮件标题垃圾”
解析后,我想格式化要在 CSV 文件中读取的文本并创建标题,然后只在列中导入下面的数据。最终结果应如下所示:

票号、旧源 IPIP、旧源端口、主机 IP、主机端口、
利用 2423、1.1.1.1、50、2.2.2.2、52
、SomeRANDOMexploit 2423、1.1.1.1、50、2.2.2.2、52、SomeRANDOMexploit

我找到了一种使用以下代码解析行的方法:

import re

filename = "./input.txt"
infile = open(filename, 'r')
lines = infile.readlines()
lines[0:13]

for line in lines:
    if re.match("TICKET NUMBER|OLD SOURCE IP|OLD SOURCE PORT|HOST IP|HOST PORT|EXPLOIT", line):
        print(line.strip())

infile.close()

这摆脱了电子邮件标题垃圾。
我只是不知道如何获取数据,然后将其格式化为 CSV,其中冒号可以分隔它并将标题放在列的顶部。

import csv
with open('output.txt', 'r') as in_file:
    stripped = [line.replace(":","").split() for line in in_file]
    zipped = zip([stripped]*1)

    with open('out_file.csv', 'w') as out_file:
        writer = csv.writer(out_file)
        writer.writerow(('TICKET NUMBER', 'OLD SOURCE IPIP', 'OLD SOURCE PORT', 'HOST IP', 'HOST PORT', 'EXPLOIT'))
        for group in zipped:
            writer.writerows(group)

上面的代码让我可以很好地编写标题,但它将我的文本文件中的所有内容打印到同一行中的单独列中

输出

TICKET NUMBER, OLD SOURCE IPIP, OLD SOURCE PORT, HOST IP, HOST PORT, EXPLOIT  
['TICKET', 'NUMBER2423']    ['OLD', 'SOURCE', 'IPIP', '1.1.1.1']    ['OLD', 'SOURCE', 'PORT', '50'] ['HOST', 'IP2.2.2.2']   ['HOST', 'PORT']    ['EXPLOITSomeRANDOMexploit']    ['TICKET', 'NUMBER2423']    ['OLD', 'SOURCE', 'IPIP', '1.1.1.1']    ['OLD', 'SOURCE', 'PORT', '50'] ['HOST', 'IP2.2.2.2']   ['HOST', 'PORT']    ['EXPLOITSomeRANDOMexploit']

期望的输出

TICKET NUMBER, OLD SOURCE IPIP, OLD SOURCE PORT, HOST IP, HOST PORT, EXPLOIT  
2423, 1.1.1.1, 50, 2.2.2.2, 52, SomeRANDOMexploit  
2423, 1.1.1.1, 50, 2.2.2.2, 52, SomeRANDOMexploit  

据我了解,代码是用任何内容替换冒号,然后将这两个词合二为一。另外我不知道如何让它们打印到新行。

标签: pythoncsv

解决方案


您可以使用 PythonDictWriter来帮助解决这个问题。每个匹配的行都可以分配给一个行字典。当找到不匹配的行时,可以写入该行。restval在缺少其中一个字段的情况下使用。

例如:

import csv
import re

fields = ["TICKET NUMBER", "OLD SOURCE IPIP", "OLD SOURCE PORT", "HOST IP", "HOST PORT", "EXPLOIT"]
re_valid_field = re.compile('|'.join(fields))

with open('input.txt') as f_input, open('output.csv', 'w', newline='') as f_output:
    csv_output = csv.DictWriter(f_output, fieldnames=fields, restval='')
    csv_output.writeheader()

    row = {}

    for line in f_input:
        if re_valid_field.match(line):
            key, sep, value = line.strip().partition(':')
            row[key.strip()] = value.strip()
        elif row:
            csv_output.writerow(row)
            row = {}

    # Any remaining row to be written?
    if row:
        csv_output.writerow(row)

这将创建output.csv如下:

TICKET NUMBER,OLD SOURCE IPIP,OLD SOURCE PORT,HOST IP,HOST PORT,EXPLOIT
2423,1.1.1.1,50,2.2.2.2,52,SomeRANDOMexploit
2423,1.1.1.1,50,2.2.2.2,52,SomeRANDOMexploit

推荐阅读