# Convertir archivo .bib a .csv

**URL:** <https://pyar.discourse.group/t/convertir-archivo-bib-a-csv/1257>\
**Category:** Sin categoría\
**Created:** [26 Marzo, 2024 13:41 UTC](https://pyar.discourse.group/t/convertir-archivo-bib-a-csv/1257 "2024-03-26T13:41:06Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![albertoImago](https://yyz2.discourse-cdn.com/free1/user_avatar/pyar.discourse.group/albertoimago/32/473_2.png) [@albertoImago](https://pyar.discourse.group/u/albertoImago)\
**Post date:** [26 Marzo, 2024 13:41 UTC](https://pyar.discourse.group/t/convertir-archivo-bib-a-csv/1257/1 "2024-03-26T13:41:06Z")

</div>

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?)

```auto
@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},
}

```

```auto
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.")

```

---

<div class="post-metadata">

**Author:** ![rosendoagustinayala](https://avatars.discourse-cdn.com/v4/letter/r/6f9a4e/32.png) [@rosendoagustinayala](https://pyar.discourse.group/u/rosendoagustinayala)\
**Post date:** [5 Abril, 2024 15:30 UTC](https://pyar.discourse.group/t/convertir-archivo-bib-a-csv/1257/2 "2024-04-05T15:30:48Z")

</div>

No me queda claro que querés hacer.

1. Si **necesitás** extraer las entradas, lo más fácil es usar un módulo ya hecho:

2. Si lo tuyo es un proyecto para **aprender** las bases de scripting de python, te recomiendo que, o empieces por algo más sencillo o agreges algunas funciones más; tenés sólo dos que hacen _todo_. Si es así te puedo dar algunos tips

3. No me quedó tiempo para testear bien la Expresión Regular (perdí un poco la práctica), pero al parecer para de buscar en el primer campo. SI tengo que adivinar, estan mal agrupadas las expresiones

### Recomendaciones generales:

1. Lo que no manejés fluídamente o tenga cierta complejidad, probalo primero en el intérprete; los RegEx por ejemplo.

2. Algo que muchos obvian (me incluyo) es el análisis preliminar del problema; si hacés de eso un hábito, te puede ahorrar muchos dolores de cabeza. Para mí lo más fácil es usar el mismo script:

3. Está muy bien la estructura del script, pero te recomiendo que uses dos funciones básicas para probar el código fuente, y vayas “guardando” las funciones que funcionan (valga la redundancia). Para que se entienda mejor:

4. Con respecto a formatos, mi recomendación es que investigues un poco primero, y armes una muestra mínima del formato para probar el script. En tu caso sería algo como:
