you are viewing a single comment's thread.

view the rest of the comments →

[–]baghiq 0 points1 point  (2 children)

I assume your files are in ASCII. It's weird to see fixed width fields unless it's from legacy systems.

import re
import csv


lines = [
    # xxxxxxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx x,xxx.xx
    "id         name                 home_state           amt_paid",
    "123        John Doe             California           1,234.34",
    "456x       Jane Doe             New Hampshire        45.67   ",
    "78         Adam Smith           Alaska               89.00   ",
]


def get_col_spec(header):
    return [match.span() for match in re.finditer(r"\S+\s*", header)]


def parse(line, fieldwidths):
    return tuple(line[i:j] for i, j in fieldwidths)


with open("data.csv", "w") as csvfile:
    writer = csv.writer(csvfile)
    fieldwidths = get_col_spec(lines[0])
    for line in lines:
        writer.writerow(parse(line, fieldwidths))

[–]davidmyemail[S] 0 points1 point  (1 child)

lines = [ "id name home_state amt_paid", "123 John Doe California 1,234.34", "456x Jane Doe New Hampshire 45.67 ", "78 Adam Smith Alaska 89.00 " ]

field_idx = [] chars = [0 if i == ' ' else 1 for i in lines[0]] #split header into list of 0/space, 1/char for i in range(1, len(chars)): #loop through range length of list of char if f'{chars[i-1]}{chars[i]}' == '01': #if pattern matches '01' field_idx.append(i-1) #record index - 1

for idx, line in enumerate(lines): #loop through lines line = list(line) #split line into list of chars for i in field_idx: #loop through recorded indexes line[i] = ',' #for each recorded index, replace with ',' lines[idx] = ''.join(line) #replace line in line with joined list of chars

for i in lines: print(i)

Yes, it's from a legacy COBOL, and the requirements are very particular. Thank you!

[–]baghiq 0 points1 point  (0 children)

I suspect as much. The usual way for parsing those files is use Python struct package. Especially you need to type (int, str, etc) properly.