web-dev-qa-db-fra.com

Comment analyser un fichier CSV dans Bash?

Je travaille sur un long script Bash. Je veux lire les cellules d'un fichier CSV dans les variables Bash. Je peux analyser les lignes et la première colonne, mais pas n'importe quelle autre colonne. Voici mon code jusqu'à présent:


  cat myfile.csv|while read line
  do
    read -d, col1 col2 < <(echo $line)
    echo "I got:$col1|$col2"
  done

C'est seulement l'impression de la première colonne. En guise de test supplémentaire, j’ai essayé ce qui suit:

read -d, x y < <(echo a,b,)

Et $ y est vide. Alors j'ai essayé:

read x y < <(echo a b)

Et $ y est b. Pourquoi?

83
User1

Vous devez utiliser IFS au lieu de -d:

while IFS=, read -r col1 col2
do
    echo "I got:$col1|$col2"
done < myfile.csv

Notez que pour l'analyse CSV à usage général, vous devez utiliser un outil spécialisé capable de gérer les champs entre guillemets avec des virgules internes, entre autres problèmes que Bash ne peut pas gérer seul. Des exemples de tels outils sont cvstool et csvkit .

166
Dennis Williamson

De la page man:

-d delim Le premier caractère de delim est utilisé pour terminer la ligne de saisie, plutôt que newline.

Vous utilisez -d, qui terminera la ligne de saisie sur la virgule. Il ne lira pas le reste de la ligne. C'est pourquoi $ y est vide.

7
dogbane

Nous pouvons analyser les fichiers CSV avec des chaînes citées et délimités par say | avec le code suivant

while read -r line
do
    field1=$(echo $line | awk -F'|' '{printf "%s", $1}' | tr -d '"')
    field2=$(echo $line | awk -F'|' '{printf "%s", $2}' | tr -d '"')

    echo $field1 $field2
done < $csvFile

awk analyse les champs de chaîne en variables et tr supprime la citation. 

Légèrement plus lent car awk est exécuté pour chaque champ.

0
Maithilish