¿Cómo iterar un archivo CSV en bash?

¿Cómo iterar un archivo CSV en bash?

¿Cómo iterar un archivo que tiene comas separadas por valores?

Intenté lo siguiente:

$ cat file | tr ','  '\n' > /tmp/f1
$ while read -r line;do 
   echo $line;
done < /tmp/f1

¿Cómo puedo iterar sobre el contenido de la primera línea sin crear un archivo temporal?

¿Algunas ideas?

Respuesta1

En primer lugar,evite realizar análisis de texto con bucles de shell. Es difícil de hacer, fácil de equivocarse y muy difícil de leer. Y lento. Muy, muy, lento. En su lugar, utilice algo como awkque esté diseñado específicamente para leer por "campos". Por ejemplo, con este archivo de entrada:

foo, bar, baz
oof, rab, zab

Puede leer cada campo separado por comas usando awk -F,para establecer el separador de campo en ,:

$ awk -F, '{ print "The 1st field is",$1,"the 2nd", $2,"and the 3rd", $3}' file
The 1st field is foo the 2nd  bar and the 3rd  baz
The 1st field is oof the 2nd  rab and the 3rd  zab

Incluso si insistes en hacerlo en el shell, no necesitas el archivo temporal ni tr. Se puede while readseparar por comas:

$ while IFS=, read -r one two three; do 
    echo "The 1st field is $one, the 2nd $two and the 3rd $three"; 
  done < file
The 1st field is foo, the 2nd  bar and the 3rd  baz
The 1st field is oof, the 2nd  rab and the 3rd  zab

Respuesta2

Los campos en un archivo csv pueden abarcar varias líneas, por esta razón y otras, es por eso que preferí usarxsvcuando tuve que analizar csv.

Una forma de analizar un archivo csv con bash y xsv puede ser:

csvFile="myfile.csv"
lengthItems=$((($(xsv count "$csvFile") - 1 ))) # -1 because for loop start at 0

for i in $( seq 0 "$lengthItems" ); do

    row="$(xsv slice -i "$i" "$csvFile")" # real magic happening here

    # Do what you want with your $row here  
    
done

información relacionada