Cómo analizar datos CSV en Bash

Jane Kelly / Shutterstock.com

Los archivos de valores separados por comas (CSV) son uno de los formatos más comunes para los datos exportados. En Linux, podemos leer archivos CSV usando comandos Bash. Pero puede volverse muy complicado, muy rápidamente. Echaremos una mano.

Índice de contenidos
  1. ¿Qué es un archivo CSV?
  2. Algunos datos de muestra
  3. Análisis de datos desde el archivo CSV
  4. Selección de campos
  5. Hasta ahora, todo bien. Pero ...
  6. Una forma segura de desinfectar datos CSV
  7. Verás mucho CSV

¿Qué es un archivo CSV?

Un archivo de valores separados por comas es un archivo de texto que contiene datos tabulados. CSV es un tipo de datos delimitados. Como su nombre indica, una coma ",”Se utiliza para separar cada campo de datos, o valor—De sus vecinos.

CSV está en todas partes. Si una aplicación tiene funciones de importación y exportación, casi siempre admitirá CSV. Los archivos CSV son legibles por humanos. Puede mirar dentro de ellos con menos, abrirlos en cualquier editor de texto y moverlos de un programa a otro. Por ejemplo, puede exportar los datos de una base de datos SQLite y abrirlos en LibreOffice Calc.

Sin embargo, incluso CSV puede volverse complicado. ¿Quieres tener una coma en un campo de datos? Ese campo debe tener comillas """Envuelto a su alrededor. Para incluir comillas en un campo, cada comilla debe ingresarse dos veces.

Por supuesto, si está trabajando con CSV generado por un programa o secuencia de comandos que ha escrito, es probable que el formato CSV sea simple y directo. Si se ve obligado a trabajar con formatos CSV más complejos, siendo Linux Linux, también existen soluciones que podemos usar para eso.

Algunos datos de muestra

Puede generar fácilmente algunos datos CSV de muestra, utilizando sitios como Online Data Generator. Puede definir los campos que desea y elegir cuántas filas de datos desea. Sus datos se generan utilizando valores ficticios realistas y se descargan a su computadora.

Creamos un archivo que contiene 50 filas de información ficticia de empleados:

  • identificación: Un valor entero único simple.
  • primer nombre: El primer nombre de la persona.
  • apellido: El apellido de la persona.
  • título profesional: El cargo de la persona.
  • dirección de correo electrónico: la dirección de correo electrónico de la persona.
  • rama: La sucursal de la empresa en la que trabajan.
  • estado: El estado en el que se encuentra la sucursal.

Algunos archivos CSV tienen una línea de encabezado que enumera los nombres de los campos. Nuestro archivo de muestra tiene uno. Aquí está la parte superior de nuestro archivo:

El archivo CSV de muestra

La primera línea contiene los nombres de los campos como valores separados por comas.

Análisis de datos desde el archivo CSV

Escribamos un script que lea el archivo CSV y extraiga los campos de cada registro. Copie este script en un editor y guárdelo en un archivo llamado "field.sh".

#! /bin/bash

while IFS="," read -r id firstname lastname jobtitle email branch state
do
  echo "Record ID: $id"
  echo "Firstname: $firstname"
  echo " Lastname: $lastname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(tail -n +2 sample.csv)

Hay bastante contenido en nuestro pequeño guión. Vamos a desglosarlo.

estamos usando un while círculo. Siempre y cuando el while círculo condición se resuelve en verdadero, el cuerpo del while se ejecutará el bucle. El cuerpo del bucle es bastante simple. Una coleccion de echo Las declaraciones se utilizan para imprimir los valores de algunas variables en la ventana del terminal.

los while la condición del bucle es más interesante que el cuerpo del bucle. Especificamos que debe usarse una coma como separador de campo interno, con el IFS="," declaración. El IFS es una variable de entorno. los read El comando se refiere a su valor al analizar secuencias de texto.

estamos usando el read de comando -r (retener barras invertidas) para ignorar cualquier barra invertida que pueda haber en los datos. Serán tratados como personajes normales.

El texto que el read Los análisis de comandos se almacenan en un conjunto de variables con el nombre de los campos CSV. Fácilmente podrían haber sido nombrados field1, field2, ... field7 pero los nombres significativos hacen la vida más fácil.

Los datos se obtienen como salida del tail dominio. estamos usando tail porque nos brinda una manera simple de saltar la línea de encabezado del archivo CSV. los -n +2 (número de línea) opción dice tail para empezar a leer en la línea número dos.

los <(...) constructo se llama sustitución de proceso. Hace que Bash acepte la salida de un proceso como si viniera de un descriptor de archivo. Luego se redirige a la while bucle, proporcionando el texto que el read el comando analizará.

Haga que el script sea ejecutable usando el chmod dominio. Deberá hacer esto cada vez que copie una secuencia de comandos de este artículo. Sustituya el nombre del script apropiado en cada caso.

chmod +x field.sh

Haciendo un script ejecutable con chmod

Cuando ejecutamos el script, los registros se dividen correctamente en sus campos constituyentes, con cada campo almacenado en una variable diferente.

./field.sh

El archivo CSV analizado por el script field.sh.

Cada registro se imprime como un conjunto de campos.

Selección de campos

Tal vez no queramos o necesitemos recuperar todos los campos. Podemos obtener una selección de campos incorporando el cut dominio.

Este script se llama "select.sh".

#!/bin/bash

while IFS="," read -r id jobtitle branch state
do
  echo "Record ID: $id"
  echo "Job Title: $jobtitle"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(cut -d "," -f1,4,6,7 sample.csv | tail -n +2)

Hemos agregado el cut comando en la cláusula de sustitución del proceso. estamos usando el -d (delimitador) opción para decir cut usar comas","Como el delimitador. los -f (campo) opción dice cut queremos los campos uno, cuatro, seis y siete. Esos cuatro campos se leen en cuatro variables, que se imprimen en el cuerpo del while círculo.

Esto es lo que obtenemos cuando ejecutamos el script.

./select.sh

Analizar el archivo CSV con field.sh para extraer una selección específica de campos

Al agregar el cut comando, podemos seleccionar los campos que queremos e ignorar los que no.

Hasta ahora, todo bien. Pero ...

Si el CSV con el que trabaja no tiene complicaciones ni comas ni comillas en los datos de campo, lo que hemos cubierto probablemente satisfaga sus necesidades de análisis de CSV. Para mostrar los problemas que podemos encontrar, modificamos una pequeña muestra de los datos para que se vean así.

id,firstname,lastname,job-title,email-address,branch,state
1,Rosalyn,Brennan,"Steward, Senior",[email protected],Minneapolis,Maryland
2,Danny,Redden,"Analyst ""Budget""",[email protected],Venice,North Carolina
3,Lexi,Roscoe,Pharmacist,,Irlington,Vermont
  • El registro uno tiene una coma en el job-title campo, por lo que el campo debe estar entre comillas.
  • El registro dos tiene una palabra entre dos juegos de comillas en el jobs-title campo.
  • El registro tres no tiene datos en el email-address campo.

Estos datos se guardaron como "sample2.csv". Modifique su script "field.sh" para llamar a "sample2.csv" y guárdelo como "field2.sh".

#! /bin/bash

while IFS="," read -r id firstname lastname jobtitle email branch state
do
  echo "Record ID: $id"
  echo "Firstname: $firstname"
  echo " Lastname: $lastname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo " Branch: $branch"
  echo " State: $state"
  echo ""
done < <(tail -n +2 sample2.csv)

Cuando ejecutamos este script, podemos ver grietas que aparecen en nuestros analizadores CSV simples.

./field2.sh

Ejecutando el campo2.sh

El primer registro divide el campo del título del trabajo en dos campos y trata la segunda parte como la dirección de correo electrónico. Cada campo después de este se desplaza un lugar a la derecha. El último campo contiene tanto el branch y el state valores.

Un registro con un campo dividido en dos campos

El segundo registro conserva todas las comillas. Solo debe tener un par de comillas alrededor de la palabra "Presupuesto".

Un registro con comillas mal manejadas

El tercer registro en realidad maneja el campo que falta como debería. Falta la dirección de correo electrónico, pero todo lo demás es como debería ser.

Un registro con un campo faltante, que se maneja correctamente

Contrariamente a la intuición, para un formato de datos simple, es muy difícil escribir un analizador CSV robusto de casos generales. Herramientas como awk le permitirá acercarse, pero siempre hay casos límite y excepciones que se escapan.

Intentar escribir un analizador CSV infalible probablemente no sea la mejor manera de avanzar. Un enfoque alternativo, especialmente si está trabajando con una fecha límite de algún tipo, emplea dos estrategias diferentes.

Una es usar una herramienta diseñada específicamente para manipular y extraer sus datos. El segundo es desinfectar sus datos y reemplazar escenarios problemáticos como comas incrustadas y comillas. Sus analizadores simples de Bash pueden hacer frente al CSV compatible con Bash.

El kit de herramientas CSV csvkit es una colección de utilidades creadas expresamente para ayudar a trabajar con archivos CSV. Deberá instalarlo en su computadora.

Para instalarlo en Ubuntu, use este comando:

sudo apt install csvkit

Instalación de csvkit en Ubuntu

Para instalarlo en Fedora, debe escribir:

sudo dnf install python3-csvkit

Instalación de csvkit en Fedora

En Manjaro el comando es:

sudo pacman -S csvkit

Instalación de csvkit en Manjaro

Si le pasamos el nombre de un archivo CSV, el csvlook La utilidad muestra una tabla que muestra el contenido de cada campo. El contenido del campo se muestra para mostrar lo que representan los contenidos del campo, no como están almacenados en el archivo CSV.

Intentemos csvlook con nuestro problemático archivo “sample2.csv”.

csvlook sample2.csv

CSV problemático analizado correctamente por csvlook

Todos los campos se muestran correctamente. Esto prueba que el problema no es el CSV. El problema es que nuestros scripts son demasiado simples para interpretar el CSV correctamente.

Para seleccionar columnas específicas, utilice el csvcut dominio. los -c La opción (columna) se puede usar con nombres de campo o números de columna, o una combinación de ambos.

Supongamos que necesitamos extraer el nombre y el apellido, los cargos y las direcciones de correo electrónico de cada registro, pero queremos que el orden de los nombres sea "apellido, nombre". Todo lo que tenemos que hacer es poner los nombres de los campos o números en el orden que los queremos.

Estos tres comandos son todos equivalentes.

csvcut -c lastname,firstname,job-title,email-address sample2.csv
csvcut -c lastname,firstname,4,5 sample2.csv
csvcut -c 3,2,4,5 sample2.csv

Selección de campos en un orden preferido con csvcut

Podemos agregar el csvsort comando para ordenar la salida por un campo. estamos usando el -c (columna) para especificar la columna por la que ordenar y la -r (reversa) opción para ordenar en orden descendente.

csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r

Seleccionando campos y ordenándolos por una sola columna

Para hacer que la salida sea más bonita, podemos pasarla csvlook .

csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r | csvlook

Usando csvlook para imprimir bastante la selección ordenada de campos

Un buen toque es que, aunque los registros están ordenados, la línea de encabezado con los nombres de los campos se mantiene como la primera línea. Una vez que estemos contentos de tener los datos de la manera que queremos, podemos eliminar el csvlook desde la cadena de comandos y cree un nuevo archivo CSV redirigiendo la salida a un archivo.

Agregamos más datos al "sample2.file", eliminamos el csvsort y creó un nuevo archivo llamado "sample3.csv".

csvcut -c 3,2,4,5 sample2.csv > sample3.csv

Una forma segura de desinfectar datos CSV

Si abre un archivo CSV en LibreOffice Calc, cada campo se colocará en una celda. Puede usar la función de buscar y reemplazar para buscar comas. Puede reemplazarlos con "nada" para que desaparezcan, o con un carácter que no afecte el análisis de CSV, como un punto y coma ";"Por ejemplo.

No verá las comillas alrededor de los campos citados. Las únicas comillas que verá son las comillas incrustadas en el interior datos de campo. Estos se muestran como comillas simples. Encontrar y reemplazar estos con un solo apóstrofo "'”Reemplazará las comillas dobles en el archivo CSV.

Uso de Buscar y reemplazar de LibreOffice Calc para reemplazar las comillas con apóstrofes

Hacer la búsqueda y el reemplazo en una aplicación como LibreOffice Calc significa que no puede eliminar accidentalmente ninguna de las comas separadoras de campo, ni eliminar las comillas alrededor de los campos citados. Solo cambiarás el valores de datos de campos

Cambiamos todas las comas en los campos con punto y coma y todas las comillas incrustadas con apóstrofes y guardamos nuestros cambios.

El archivo CSV modificado

Luego creamos un script llamado "field3.sh" para analizar "sample3.csv".

#! /bin/bash

while IFS="," read -r lastname firstname jobtitle email
do
  echo " Lastname: $lastname"
  echo "Firstname: $firstname"
  echo "Job Title: $jobtitle"
  echo "Email add: $email"
  echo ""
done < <(tail -n +2 sample3.csv)

Veamos qué obtenemos cuando lo ejecutamos.

./field3.sh

Una sección de CSV analizado correctamente

Nuestro analizador simple ahora puede manejar nuestros registros previamente problemáticos.

Verás mucho CSV

Podría decirse que CSV es lo más parecido a una lengua común para los datos de la aplicación. La mayoría de las aplicaciones que manejan algún tipo de datos admiten la importación y exportación de CSV. Saber cómo manejar CSV, de una manera realista y práctica, te será de gran utilidad.

RELACIONADO: 9 ejemplos de secuencias de comandos Bash para comenzar en Linux

Descubre más contenido

Subir Change privacy settings