Python: análisis de texto estructurado a formato CSV

Quiero convertir archivos de texto plano estructurado al formato CSV usando Python.

La entrada se ve así

[-------- 1 -------] Version: 2 Stream: 5 Account: A [...] [------- 2 --------] Version: 3 Stream: 6 Account: B [...] 

Se supone que la salida se verá así:

 Version; Stream; Account; [...] 2; 5; A; [...] 3; 6; B; [...] 

Es decir, la entrada son registros de texto estructurados delimitados por [--------] y que contienen : -pares y la salida debe ser CSV que contiene un registro por línea.

Puedo recuperar las : -parejas en formato CSV a través de

 colonseperated = re.compile(' *(.+) *: *(.+) *') fixedfields = re.compile('(\d{3} \w{7}) +(.*)') 

– pero tengo problemas para reconocer el inicio y el final de los registros de texto estructurado y con la reescritura como registros de línea CSV. Además, me gustaría poder separar diferentes tipos de registros, es decir, distinguir entre los tipos de registros, digamos, Version: 2 y Version: 3 .

Leer la lista no es tan difícil:

 def read_records(iterable): record = {} for line in iterable: if line.startswith('[------'): # new record, yield previous if record: yield record record = {} continue key, value = line.strip().split(':', 1) record[key.strip()] = value.strip() # file done, yield last record if record: yield record 

Esto produce diccionarios de su archivo de entrada.

A partir de esto, puede producir una salida CSV utilizando el módulo csv , específicamente la clase csv.DictWriter() :

 # List *all* possible keys, in the order the output file should list them headers = ('Version', 'Stream', 'Account', ...) with open(inputfile) as infile, open(outputfile, 'wb') as outfile: records = read_records(infile) writer = csv.DictWriter(outfile, headers, delimiter=';') writer.writeheader() # and write writer.writerows(records) 

Cualquier clave de encabezado que falte en un registro dejará esa columna vacía para ese registro. Cualquier encabezado adicional que haya perdido generará una excepción; agregue esos a la tupla de headers , o establezca la palabra clave extrasaction en el constructor DictWriter() en 'ignore' .