在Python中读取EBCDIC文件

问题描述 投票:0回答:1

我一直在尝试读取 .ebc 文件,但无法读取。我想将其保存为 .csv 或 txt 文件。 (我是这种文件格式的新手,所以不确定如何继续前进)

是文件的描述,数据可公开获取此处(在地下注入控制数据下)

我已经尝试过这些线程,但没有任何效果:读取大型机 EBCDIC 文件如何通过 python 在笔记本电脑上打开 .ebc (ebcdic) 文件? 使用 Python 2 将 EBCDIC 文件转换为 ASCII

1、不打印任何东西:

import codecs

with open("uif700a.txt", "rb") as ebcdic:
    ascii_txt = codecs.decode(ebcdic.read(), "cp500")
    print(ascii_txt)

2、不打印任何东西

with open("uif700.ebc", encoding='cp500') as f:
    print(f.read())

3,文件也可以作为 ASCII,所以我尝试了:

data = pd.read_csv('uif700a.txt', on_bad_lines='skip', encoding = "cp037",header=None)

EmptyDataError:没有要从文件中解析的列

python file decoding ebcdic
1个回答
0
投票

也许这个回复现在已经太晚了(5个月后),但我会尝试一下。 几年前我在使用 RRC EBC 文件时遇到了同样的问题。我必须联系 IBM 朋友才能解决这个问题。 这就是我所做的。希望有帮助。

注意:这不是我的全部代码,所以它可能不会像现在这样运行。

  1. 它不是字符分隔文件(如 csv)。这是一个固定长度的数据集。在我的解决方案中,我在 YAML 中创建了一个配置文件来解码位置:
  • 总行大小
  • 索引 ID (RRC-TAPE-RECORD-ID)
  • 文件名(UIC-CNTL-NO)
  • 字符开始(上面的字段从1开始)
  • 长度(根据您共享的文档,上面字段的长度为 9)
  • 类型(因为数字需要特殊转换。字符串更简单)

YAML:

"GLOBAL":
  record_length: 22
'01':
  RRC-TAPE-RECORD-ID
    start: 1
    length: 2
    type: string
  UIC-CNTL-NO:
    start: 3
    length: 9
    type: number
  ...

您需要对您正在使用的所有字段执行此操作(乏味)。请注意,如果字段中的值不占整个长度,则末尾将填充空格

  1. 将整个文件分成块。每个块以规范上的长度结束(您的情况是 622,它在配置文件中)

Python 3:

chunks = []
with open(path, 'rb') as f:
    data = f.read()
    print(f'Data size: {len(data):,}')
    n = config['GLOBAL']['record_length']
    for i in range(0,len(data),n):
        chunks.append(data[i:i+n])

现在您有一个值列表,但尚未解码。它们都是二进制的。

  1. 创建一个函数来解码数字。这是解决这个问题的挑战性部分,但最终并不复杂

Python 3:

def packed( bytes ): #take the bytes
    n= [ '' ]
    for b in bytes[:-1]: # decode bytes to number
            hi, lo = divmod( b, 16 ) 
            n.append( str(hi) )
            n.append( str(lo) )
    digit, sign = divmod( bytes[-1], 16 )
    n.append( str(digit) )
    if sign in (0x0b, 0x0d ): # Take care of Sign
            n[0]= '-'
    else:
            n[0]= '+'
    return float(''.join(n))
  1. 使用库来解码字符串

Python 3:

import codecs
#Do this for EVERY string field in the Config YAML file
decode_text = codecs.getdecoder('cp037')
record_type = decode_text(chunk[0:2])[0]
  1. 将它们放在一起,在每行和每列上循环,然后你最终可以保存到 Pandas

Python 3:

for chunk in chunks:
   #all fields inside RRC-TAPE_RECORD-ID. The first col for that table will be alway '01'
   config_fields = config['01']
   # Get the name of all fields. Those are your columns
   cols = list(temp.keys())[1:]
    for i in cols:
        variable = temp[i]
        start = variable['start']
        length = variable['length']
        if variable['type'] == 'display':
            result = decode_text(chunk[start-1:start-1+length].strip())[0]
        elif variable['type'] == 'packed':
            result = packed(chunk[start-1:start-1+length])
        line.append(result)
lines.append(line)
df = pd.DataFrame(lines, columns=cols)
return df
© www.soinside.com 2019 - 2024. All rights reserved.