使用正确的python包获得结果
我有一个固定宽度的文本文件,我必须将其转换为.csv,其中所有数字都必须转换为整数(无逗号、美元符号、引号等)。我目前使用纯python解析文本文件,但在使用正确的包时,我似乎陷入了僵局 有了csv,我可以用writer.writerows代替print语句将输出写入csv文件,但问题是我必须在这些行之后添加更多的列(如日期和时间),而csv似乎无法做到这一点。我也无法找到一种方法来将文本文档中的空白列转换为输出中的空白列。csv似乎写得井然有序 我正在阅读xlsxwriter上的文档,了解如何使用设置的格式写入各个列,但我不确定它是否符合我的.csv要求 我的输入文本在整个50k行文档中有一系列随机分组,但遵循以下格式使用正确的python包获得结果,python,csv,xlsxwriter,Python,Csv,Xlsxwriter,我有一个固定宽度的文本文件,我必须将其转换为.csv,其中所有数字都必须转换为整数(无逗号、美元符号、引号等)。我目前使用纯python解析文本文件,但在使用正确的包时,我似乎陷入了僵局 有了csv,我可以用writer.writerows代替print语句将输出写入csv文件,但问题是我必须在这些行之后添加更多的列(如日期和时间),而csv似乎无法做到这一点。我也无法找到一种方法来将文本文档中的空白列转换为输出中的空白列。csv似乎写得井然有序 我正在阅读xlsxwriter上的文档,了解如何
* START ******************************************************************************************************************** START *
* START ******************************************************************************************************************** START *
* START ******************************************************************************************************************** START *
1--------------------
1ANTECR09 CHEK DPCK_R_009
TRANSIT EXTRACT SUB-SYSTEM
CURRENT DATE = 08/03/2017 JOURNAL REPORT PAGE 1
PROCESS DATE =
ID = 022000046-MNT
FILE HEADER = H080320171115
+____________________________________________________________________________________________________________________________________
R T SEQUENCE CR BT A RSN ITEM ITEM CHN USER REASO
NBR NBR OR PIC NBR DB NBR NBR COD AMOUNT SERIAL IND .......FIELD.. DESCR
5,556 01 7450282689 C 538196640 9835177743 15 $9,064.81 00 CREDIT
5,557 01 7450282690 D 031301422 362313705 38 $592.35 43431 DR CR
5,558 01 7450282691 D 021309379 601298839 38 $1,491.04 44896 DR CR
5,559 01 7450282692 D 071108834 176885 38 $6,688.00 1454 DR CR
5,560 01 7450282693 D 031309123 1390001566241 38 $293.42 6878 DR CR
我的代码当前解析此文档,提取日期、时间,并仅打印序列号以42开头且CR为“C”的行
实现这个结果的最干净的方法是什么?我应该先写出解析,还是先在一个包中完成所有工作,朝着正确的方向前进?
谢谢你的帮助
编辑:
标题块(介于1----------和+\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu之间)在整个文档中重复出现,以及由-------
我建议对固定宽度块进行切片,以便通过固定宽度字段进行解析。类似于以下(不完整)代码: 输出为:
5556,01,4250282689,C,...
基于未定义列中看似虚假的值进行更新
根据提供的关于“虚假”列/字段的新信息(很少出现),这可能是一个迭代过程
我的建议是缩小(适当地!)所需字段的宽度。例如,如果上面的行[12:14]
中有虚假数据,则可以将(12,22,'t_nbr')
的元组更改为(14,22,'t_nbr')
,以“跳过”虚假字段
另一种方法是在元组列表中添加一个“垃圾”字段来处理这些类型的行。无论“伪”字段出现在哪里,“垃圾”字段都会简单地使用它
如果您需要这些字段,与“垃圾”字段方法相同的一般方法仍然适用,但您需要保存数据
基于随机分隔符的更新
如果它们相对一致,我只需添加一些逻辑(如上所述)来“检测”分隔符并跳过它们。我建议对固定宽度块进行切片,以便通过固定宽度字段进行解析。类似于以下(不完整)代码: 输出为:
5556,01,4250282689,C,...
基于未定义列中看似虚假的值进行更新
根据提供的关于“虚假”列/字段的新信息(很少出现),这可能是一个迭代过程
我的建议是缩小(适当地!)所需字段的宽度。例如,如果上面的行[12:14]
中有虚假数据,则可以将(12,22,'t_nbr')
的元组更改为(14,22,'t_nbr')
,以“跳过”虚假字段
另一种方法是在元组列表中添加一个“垃圾”字段来处理这些类型的行。无论“伪”字段出现在哪里,“垃圾”字段都会简单地使用它
如果您需要这些字段,与“垃圾”字段方法相同的一般方法仍然适用,但您需要保存数据
基于随机分隔符的更新
如果它们相对一致,我只需添加一些逻辑(如上所述)来“检测”分隔符并跳过它们。我没有真正研究过这一点,但请记住,作为一般规则,程序包可以帮助您解决常见问题,如果您发现某些软件包使处理任务变得更加复杂甚至不可能,那么使用您的自定义逻辑是非常好的。我没有真正研究过这一点,但请记住,作为一般规则,软件包可以帮助您解决常见问题,如果您发现某个软件包使处理任务变得更加复杂,甚至不可能,那么使用自定义逻辑就完全可以了。我提交的文本文件只是整个任务的一部分。我相信我在上面说过,它大约有5万条线长。数字改变,分组之间有随机字符分隔符,这就是我最初使用py逻辑搜索整个文件的原因。除了元组,还有什么方法可以解析整个文档吗?@mcclayjr01您可以发布一些“随机字符分隔符”的示例行吗?如果固定宽度布局确实是随机的,您可以尝试构建更健壮的字段检测功能,但基于上面的标题,这看起来相当困难。顺便说一句,随机分隔符也可能对某些第三方“文本表”阅读包产生不利影响,但在这里它们可能会被证明是有用的。我没有亲自尝试过,所以我不会提供解决方案。我添加了更多的例子。谈到python,我是个新手,所以我一直在学习py逻辑。我一直在努力阅读文档以找到最佳解决方案,最终产品可能会使用多个软件包,但我很难确定哪些软件包能够很好地协同工作,以及如何将我以前的py逻辑与正确的软件包结合起来。我提交的文本文件只是整个过程的一部分。我相信我在上面说过,它大约有5万条线长。数字改变,分组之间有随机字符分隔符,这就是我最初使用py逻辑搜索整个文件的原因。除了元组,还有什么方法可以解析整个文档吗?@mcclayjr01您可以发布一些“随机字符分隔符”的示例行吗
data = """ 5,556 01 4250282689 C 538196640 9835177743 15 $9,064.81 00
CREDIT
5,557 01 7450282690 D 031301422 362313705 38 $592.35 43431
DR CR
5,558 01 7450282691 D 021309379 601298839 38 $1,491.04 44896
DR CR
"""
# list of data layout tuples (start_index, stop_index, field name)
# TODO add missing data layout tuples
data_layout = [(0, 12, 'r_nbr'), (12, 22, 't_nbr'), (22, 39, 'seq'), (39, 42, 'cr_db')]
for line in data.splitlines():
# skip "separator" lines
# NOTE this may be an iterative process to identify these
if line.startswith('-----'):
continue
record = {}
for start_index, stop_index, name in data_layout:
record[name] = line[start_index:stop_index].strip()
# your conditional (seems inconsistent with text)
if record['seq'].startswith('42') and record['cr_db'] == 'C':
# perform any special handling for each column
record['r_nbr'] = record['r_nbr'].replace(',', '')
# TODO other special handling (like $)
print('{r_nbr},{t_nbr},{seq},{cr_db},...'.format(**record))
5556,01,4250282689,C,...