我正在尝试将我认为是固定宽度的文件读入Python。以前通常不需要处理编码问题,这个问题有点难倒我。
文件没有扩展名,我相信它来自大型机 cobol 系统。当我在 sublime 中打开它时,我看到这个:
5cf0 f1f2 f4f2 f0f2 f401 489c 024c f0f1
f2f5 f2f0 f2f4 0148 9c02 5c00 1c00 0000
0000 0000 0000 0040 4040 4040 4040 4040
4040 4040 4040 4040 4040 4040 4040 4040
... and so on
我看到的最好的编码是 cp037 或 cp1140:
with open(said_file, encoding='cp1140') as f:
data = f.read()
产生一些清晰的材料 - 文件日期等。 经过一些暴力破解后,看起来 437 是固定宽度行的长度。这是上述标题之后的一行的前几个字符:
*01242024\x01çæ\x02<01252024\x01çæ\x02*\x00\x1c\x00\x00\x00... <to len 437, I suppose this is a header>
C\x010026987100\x01\x00\x01çæ\x00æ2... < to len 437 * 2, I suppose this is the actual start of the data> etc
...
此文件附带一个 .dtd xml 文件,用于描述固定宽度的性质。该变音符 (ç) 频繁出现在偏移量 14 长度 3 处,.dtd 文件将其描述为“SIGNED,TRAILING_SIGN”。我不确定如何使用 struct 库之类的东西将其准确地转换为 Python。
我怎样才能更好地对这些数据进行逆向工程,最终目标是使其可以在 Pandas 之类的东西中使用?在我听到其他消息之前,我非常怀疑这个变音符号是否确实存在,而是翻译中发生的编码问题。
我已经要求提供 cobol 剧本,但在那之前我有兴趣了解可以用来更好地对该文件进行逆向工程的其他技术。
既然你有了结构,那就用它吧。
重要的是不使用任何编码而是以二进制方式读取文件。然后将其拆分为多个部分,并将文本部分作为字节数组一一处理,然后使用其具有的任何编码进行转换。除了“纯文本”和“编码的 8 位 EBCDIC”之外,您可能还有压缩数字,可能是二进制数字,也可能是 UTF-8 和/或 UTF-16 - 所有这些都混合在一起。
这看起来就像一个没有标题的连续“文本”文件(固定长度),其中包含二进制数据或(很可能)PACKED-DECIMAL
/二进制编码的十进制。查看
https://en.wikipedia.org/wiki/EBCDIC(使用正确的子编码来获取非英语字符)这可能是
5+
(或星号,见下一条评论)+
01242024
(文本或数字显示)+
01489+
(每个半字节是一个数字,最后半字节0x0c为正,负为0x0d ,无符号 0x0f,在 COBOL copybook 中
PIC S9(05) PACKED-DECIMAL
(也可以是
S9(04)
,在这种情况下,前导零只是必要的填充字节)+
01252024
+
01489+
+
025+
+
001+
+ 一些二进制零(这可能是一个计算字段,或者其他东西,然后注意字节排序问题!)等等。在数字显示的情况下,也可能存在符号的“过度打孔”。检查您的 dtd 是否足以获取结构,或者只是等待副本并使用
上的IBM 文档熟悉 COBOL 定义。