hola gente, soy nuevo en python así que es probable que mi problema sea básico, pero sencillamente no lo veo.
Hice un script que convierte archivos de biblatex a csv (ojo con esto no es bibtex, biblatex es más moderno) para luego poder insertarlos en una base de datos SQLite, sospecho que el problema lo tengo con la expresión regular que lee el archivo (pero no estoy seguro), la cuestión es que necesito escapar la barra invertida, ya que la misma se utiliza dentro de los campos, el script lo utilizo desde consola con la lógica de:
python script.py archivo.bib archivo.csv
no obtengo ningún error, pero tampoco hace lo esperado, copia un registro bib de ejemplo y el script (no encuentro el modo de adjuntar archivos, ¿es posible?)
@InCollection{Gene2011,
hyphenation = {spanish},
author = {Gené, Marcela},
booktitle = {\enquote{Travesías de la imagen}. Historia de las artes visuales en la Argentina},
date = {2011},
editor = {María Isabel Baldasarre and Silvia Dolinko},
keywords = {listar},
location = {Buenos Aires},
pages = {95-118},
publisher = {EDUNTREF},
title = {Varones domados. \emph{Family strips} de los años veinte},
volume = {1},
}
import re
import csv
import sys
# Función para leer un archivo .bib y extraer la información
def leer_bib(archivo):
with open(archivo, 'r', encoding='utf-8') as f:
texto = f.read()
# Expresión regular para capturar entradas con llaves
entradas = re.findall(r'@(\w+)\{(.*?)\}(?:\r?\n)?', texto, re.DOTALL)
# Convertir las entradas a diccionarios
datos = []
for entrada in entradas:
tipo_entrada, contenido = entrada
campos = dict(re.findall(r'(\w+)\s*=\s*(?:{([^{}]*?)}|"([^"]*?)")', contenido))
campos['tipoEntrada'] = tipo_entrada.lower() # Convertir a minúsculas
# Escapar las barras invertidas y comillas dobles en el contenido de los campos
for key, value in campos.items():
if value is not None:
value = value.replace('\\', '\\\\').replace('"', '""')
campos[key] = value.strip()
datos.append(campos)
return datos
# Función para escribir la información en un archivo CSV
def escribir_csv(datos, archivo_salida):
# Lista de nombres de columna en el orden proporcionado
columnas = ['tipoEntrada', 'citationKey', 'keywords', 'author', 'bookAuthor', 'editor', 'editorA', 'editorB', 'editorC', 'afterword', 'commentator', 'translator', 'holder', 'shortTitle', 'short', 'editorType', 'editorAtype', 'editorBtype', 'editorCtype', 'foreword', 'introduction', 'annotator', 'gender', 'nameAddOn', 'title', 'indexTitle', 'bookTitle', 'mainTitle', 'journalTitle', 'issueTitle', 'eventTitle', 'reprintTitle', 'series', 'bookTitleAddOn', 'mainTitleAddOn', 'journalTitleAddOn', 'issueTitleAddOn', 'eventTitleAddOn', 'chapter', 'volume', 'edition', 'pubState', 'year', 'date', 'urlDate', 'volumes', 'part', 'issue', 'eventDate', 'origDate', 'version', 'location', 'publisher', 'institution', 'organization', 'page', 'pagination', 'hyphenation', 'langId', 'language', 'origLocation', 'origPublisher', 'pageTotal', 'venue', 'bookPagination', 'langIdOpts', 'origLanguage', 'isan', 'isbn', 'ismn', 'isrn', 'issn', 'iswc', 'url', 'doi', 'eid', 'eprinttype', 'eprint', 'entrysubtype', 'label', 'howpublisher', 'addendum', 'shorthand', 'shorthandintro', 'etiquetas', 'options', 'ids', 'related', 'relatedType', 'relatedString', 'entryset', 'crossref', 'xref', 'xdata', 'presort', 'sortkey', 'sortname', 'sortshorthand', 'sorttitle', 'indexsorttitle', 'sortyear', 'file', 'abstract', 'library', 'note', 'annotation', 'number', 'creationdate', 'type']
# Escribir los datos en un archivo CSV con punto y coma como separador
with open(archivo_salida, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=columnas, delimiter=';')
writer.writeheader()
for dato in datos:
# Eliminar campos no deseados del diccionario
dato_filtrado = {key: value for key, value in dato.items() if key in columnas}
writer.writerow(dato_filtrado)
# Leer el archivo CSV recién creado y reemplazar los encabezados year por yearY y date por dateD
with open(archivo_salida, 'r', encoding='utf-8') as f:
lines = f.readlines()
# Reemplazar los encabezados year y date
if 'year' in columnas:
lines[0] = lines[0].replace('year', 'yearY')
if 'date' in columnas:
lines[0] = lines[0].replace('date', 'dateD')
# Escribir las líneas modificadas de nuevo en el archivo CSV
with open(archivo_salida, 'w', newline='', encoding='utf-8') as f:
f.writelines(lines)
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Uso: python script.py archivo.bib archivo.csv")
sys.exit(1)
archivo_entrada = sys.argv[1]
archivo_salida = sys.argv[2]
# Leer el archivo .bib y convertirlo a datos
datos = leer_bib(archivo_entrada)
# Escribir los datos en un archivo CSV
escribir_csv(datos, archivo_salida)
print("Archivo CSV generado correctamente.")