python - 解析文本文件并格式化为 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
据我了解,代码是用任何内容替换冒号,然后将这两个词合二为一。另外我不知道如何让它们打印到新行。
解决方案
您可以使用 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
推荐阅读
- reactjs - Redux 状态和 useState 不同步
- laravel - 为什么 laravel 返回一个空数组来表示一个有很多关系?
- python - 将列表加入分隔符分隔的列表列表
- reactjs - 使用时 useParams 不起作用
} /> 而不是 - python - 计算 tensorflow 创建的矩阵中变量的标准偏差
- java - 如何为kafka主题分配优先级
- design-patterns - DDD - 如何设计文件系统域
- android-fragments - 在视图寻呼机 2 中处理 Exo 播放器实例的创建和发布的正确方法是什么
- julia - 导入数组数据并以特定格式保存数组数据的最快方法是什么?
- android - 可以让多个 youtube 播放器播放相同的内容吗?