Python 将文本文件和格式解析为CSV

Python 将文本文件和格式解析为CSV,python,csv,Python,Csv,所以,在我发布这个问题之前,我发现了一个与我的问题相似但不确切的问题。 我有一个需要解析的文本文件 票号:2423 旧来源IPIP:1.1.1.1 旧源端口:50 主机IP:2.2.2.2 主机端口:52 利用:一些随机利用 一堆随机电子邮件头garabage 票号:2423 旧来源IPIP:1.1.1.1 旧源端口:50 主机IP:2.2.2.2 主机端口:52 利用,利用 我想解析掉所有“一堆随机邮件头垃圾” 在它被解析后,我想格式化文本以在CSV文件中读取,并创建标题,然后只导入以下列中

所以,在我发布这个问题之前,我发现了一个与我的问题相似但不确切的问题。

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

票号:2423
旧来源IPIP:1.1.1.1
旧源端口:50
主机IP:2.2.2.2
主机端口:52
利用:一些随机利用
一堆随机电子邮件头garabage
票号:2423
旧来源IPIP:1.1.1.1
旧源端口:50
主机IP:2.2.2.2
主机端口:52
利用,利用

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

票证号、旧源IPIP、旧源端口、主机IP、主机端口、漏洞利用
2423,1.1.1.1,50,2.2.2,52等 2423,1.1.1.1,50,2.2.2,52,

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

重新导入
filename=“./input.txt”
infle=open(文件名为'r')
lines=infle.readlines()
行[0:13]
对于行中的行:
如果重新匹配(“票证号|旧源IP |旧源端口|主机IP |主机端口|利用”,行):
打印(line.strip())
infle.close()
这将清除电子邮件标题垃圾。
我只是不知道如何获取数据,然后将其格式化为CSV格式,在CSV中冒号可以对其进行分隔,并将标题放在列的顶部

导入csv
在文件中打开('output.txt','r'):
stripped=[line.replace(“:”,”).split()用于_文件中的行]
压缩=压缩([剥离]*1)
将open('out_file.csv','w')作为out_文件:
writer=csv.writer(输出文件)
writer.writerow(('TICKET NUMBER','OLD SOURCE IPIP','OLD SOURCE PORT','HOST IP','HOST PORT','aipple'))
对于zipped中的组:
writer.writerows(组)
上面的代码让我可以很好地编写标题,但它将文本文件中的所有内容打印到同一行中的单独列中

输出

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  
所需输出

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  

据我所知,代码将冒号替换为空,然后将两个单词合并为一个。另外,我不知道如何让它们打印到新的行。

您可以使用Python来帮助实现这一点。可以将每个匹配行分配给行字典。当找到不匹配的行时,可以写入该行
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
,如下所示:

票证号、旧源IPIP、旧源端口、主机IP、主机端口、漏洞
2423,1.1.1.1,50,2.2.2,52等
2423,1.1.1.1,50,2.2.2,52等

您可以使用Python来帮助实现这一点。可以将每个匹配行分配给行字典。当找到不匹配的行时,可以写入该行
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
,如下所示:

票证号、旧源IPIP、旧源端口、主机IP、主机端口、漏洞
2423,1.1.1.1,50,2.2.2,52等
2423,1.1.1.1,50,2.2.2,52等

这是否回答了您的问题@stovfl该链接有帮助,但我仍然遇到一个问题,即它在一行中创建所有内容,如上图所示。不要遵循问题代码,使用上一个答案中的方法。这是否回答了您的问题@stovfl该链接有帮助,但我仍然遇到这样的问题,即它将所有内容创建在一行中,如上图所示。不要按照问题代码,使用上一个答案中的方法。
Traceback(最近一次调用的最后一次):文件“writer7.py”,第15行,在key中,value=line.strip()。split(“:”)ValueError:没有足够的值来解包(预期2人,获得1人)
您的文件中可能有一行,例如
票号
,即没有任何
可拆分。我已将代码调整为使用
分区
,而不是
拆分
,以处理此问题。成功了!谢谢!现在,如果我可以将两个函数合并为一个脚本。
回溯(最后一次调用):文件“writer7.py”,第15行,在key中,value=line.strip().split(“:”)value错误:没有足够的值来解包(应为2,得到1)
您的文件中可能有一行,如
票号
,即没有任何
可拆分。我已将代码调整为使用
分区
,而不是
拆分
,以处理此问题。这样做了!谢谢!现在,如果我可以将两个函数合并到一个脚本中。