Les fichiers de valeurs séparées par des virgules (CSV) sont l’un des formats les plus courants pour les données exportées. Sous Linux, nous pouvons lire les fichiers CSV à l’aide des commandes Bash. Mais ça peut devenir très compliqué, très vite. Nous vous donnerons un coup de main.
Qu’est-ce qu’un fichier CSV ?
Un fichier de valeurs séparées par des virgules est un fichier texte contenant des données tabulées. CSV est un type de données délimitées. Comme son nom l’indique, une virgule « ,
” est utilisé pour séparer chaque champ de données (ou valeur) de ses voisins.
CSV est partout. Si une application a des fonctions d’importation et d’exportation, elle prendra presque toujours en charge CSV. Les fichiers CSV sont lisibles par l’homme. Vous pouvez regarder à l’intérieur avec less, les ouvrir dans n’importe quel éditeur de texte et les déplacer d’un programme à l’autre. Par exemple, vous pouvez exporter les données d’une base de données SQLite et l’ouvrir dans LibreOffice Calc.
Cependant, même CSV peut devenir compliqué. Vous voulez avoir une virgule dans un champ de données ? Ce champ doit avoir des guillemets « "
» enroulé autour de lui. Pour inclure des guillemets dans un champ, chaque guillemet doit être entré deux fois.
Bien sûr, si vous travaillez avec un CSV généré par un programme ou un script que vous avez écrit, le format CSV est susceptible d’être simple et direct. Si vous êtes obligé de travailler avec des formats CSV plus complexes, Linux étant Linux, il existe également des solutions que nous pouvons utiliser pour cela.
Quelques exemples de données
Vous pouvez facilement générer des exemples de données CSV, en utilisant des sites comme Générateur de données en ligne. Vous pouvez définir les champs souhaités et choisir le nombre de lignes de données souhaitées. Vos données sont générées à l’aide de valeurs fictives réalistes et téléchargées sur votre ordinateur.
Nous avons créé un fichier contenant 50 lignes d’informations sur les employés factices :
- identifiant: Une simple valeur entière unique.
- prénom: Le prénom de la personne.
- nom de famille: Le nom de famille de la personne.
- titre d’emploi: Intitulé du poste de la personne.
- adresse e-mail: L’adresse e-mail de la personne.
- bifurquer: La branche de l’entreprise dans laquelle ils travaillent.
- Etat: L’état dans lequel se trouve la succursale.
Certains fichiers CSV ont une ligne d’en-tête qui répertorie les noms de champs. Notre exemple de fichier en contient un. Voici le haut de notre dossier :
La première ligne contient les noms de champs sous forme de valeurs séparées par des virgules.
Analyser les données du fichier CSV
Écrivons un script qui lira le fichier CSV et extraira les champs de chaque enregistrement. Copiez ce script dans un éditeur et enregistrez-le dans un fichier appelé « 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)
Il y a pas mal de choses dans notre petit script. Décomposons-le.
Nous utilisons un while
boucler. Tant que le while
la condition de boucle devient vraie, le corps de la while
boucle sera exécutée. Le corps de la boucle est assez simple. Une collection de echo
Les instructions sont utilisées pour imprimer les valeurs de certaines variables dans la fenêtre du terminal.
Le while
condition de boucle est plus intéressante que le corps de la boucle. Nous spécifions qu’une virgule doit être utilisée comme séparateur de champ interne, avec le IFS=","
déclaration. L’IFS est une variable d’environnement. Le read
La commande fait référence à sa valeur lors de l’analyse de séquences de texte.
Nous utilisons le read
commande -r
(conserver les barres obliques inverses) pour ignorer les barres obliques inverses pouvant se trouver dans les données. Ils seront traités comme des personnages normaux.
Le texte que le read
Les analyses de commande sont stockées dans un ensemble de variables nommées d’après les champs CSV. Ils auraient tout aussi bien pu être nommés field1, field2, ... field7
mais les noms significatifs facilitent la vie.
Les données sont obtenues en sortie du tail
commande. Nous utilisons tail
car cela nous donne un moyen simple de sauter la ligne d’en-tête du fichier CSV. Le -n +2
(numéro de ligne) indique tail
commencer à lire à la ligne numéro deux.
Le <(...)
la construction s’appelle substitution de processus. Cela amène Bash à accepter la sortie d’un processus comme si elle provenait d’un descripteur de fichier. Celle-ci est ensuite redirigée vers le while
boucle, fournissant le texte que le read
commande analysera.
Rendre le script exécutable à l’aide de chmod
commande. Vous devrez le faire chaque fois que vous copierez un script de cet article. Remplacez le nom du script approprié dans chaque cas.
chmod +x field.sh
Lorsque nous exécutons le script, les enregistrements sont correctement divisés en leurs champs constitutifs, chaque champ étant stocké dans une variable différente.
./field.sh
Chaque enregistrement est imprimé sous la forme d’un ensemble de champs.
Sélection des champs
Peut-être que nous ne voulons pas ou n’avons pas besoin de récupérer tous les champs. On peut obtenir une sélection de champs en incorporant les cut
commande.
Ce script s’appelle « 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)
Nous avons ajouté le cut
commande dans la clause de substitution de processus. Nous utilisons le -d
(délimiteur) option pour dire cut
utiliser des virgules « ,
” comme délimiteur. Le -f
(champ) option indique cut
nous voulons les champs un, quatre, six et sept. Ces quatre champs sont lus dans quatre variables, qui sont imprimées dans le corps du while
boucler.
C’est ce que nous obtenons lorsque nous exécutons le script.
./select.sh
En ajoutant le cut
commande, nous pouvons sélectionner les champs que nous voulons et ignorer ceux que nous ne voulons pas.
Jusqu’ici, tout va bien. Mais…
Si le CSV que vous traitez est simple, sans virgules ni guillemets dans les données de champ, ce que nous avons couvert répondra probablement à vos besoins d’analyse CSV. Pour montrer les problèmes que nous pouvons rencontrer, nous avons modifié un petit échantillon des données pour qu’elles ressemblent à ceci.
id,firstname,lastname,job-title,email-address,branch,state 1,Rosalyn,Brennan,"Steward, Senior",Rosalyn_Brennan4351@mafthy.com,Minneapolis,Maryland 2,Danny,Redden,"Analyst ""Budget""",Danny_Redden1443@brety.org,Venice,North Carolina 3,Lexi,Roscoe,Pharmacist,,Irlington,Vermont
- L’enregistrement un a une virgule dans le
job-title
champ, de sorte que le champ doit être entouré de guillemets. - L’enregistrement deux contient un mot entouré de deux ensembles de guillemets dans le
jobs-title
domaine. - L’enregistrement trois n’a pas de données dans le
email-address
domaine.
Ces données ont été enregistrées sous « sample2.csv ». Modifiez votre script « field.sh » pour appeler le « sample2.csv » et enregistrez-le sous « 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)
Lorsque nous exécutons ce script, nous pouvons voir des fissures apparaître dans nos simples analyseurs CSV.
./field2.sh
Le premier enregistrement divise le champ de l’intitulé du poste en deux champs, traitant la seconde partie comme l’adresse e-mail. Chaque champ après celui-ci est décalé d’une place vers la droite. Le dernier champ contient à la fois les branch
et le state
valeurs.
Le deuxième enregistrement conserve tous les guillemets. Il ne devrait y avoir qu’une seule paire de guillemets autour du mot « Budget ».
Le troisième enregistrement gère en fait le champ manquant comme il se doit. L’adresse e-mail est manquante, mais tout le reste est comme il se doit.
Contre-intuitivement, pour un format de données simple, il est très difficile d’écrire un analyseur CSV robuste pour le cas général. Des outils comme awk
vous permettra de vous en approcher, mais il y a toujours des cas extrêmes et des exceptions qui se glissent.
Essayer d’écrire un analyseur CSV infaillible n’est probablement pas la meilleure voie à suivre. Une approche alternative, surtout si vous travaillez dans un délai quelconque, utilise deux stratégies différentes.
La première consiste à utiliser un outil spécialement conçu pour manipuler et extraire vos données. La seconde consiste à assainir vos données et à remplacer les scénarios problématiques tels que les virgules et les guillemets intégrés. Vos simples analyseurs Bash peuvent alors gérer le CSV compatible avec Bash.
La boîte à outils CSV csvkit
est une collection d’utilitaires expressément créés pour aider à travailler avec des fichiers CSV. Vous devrez l’installer sur votre ordinateur.
Pour l’installer sur Ubuntu, utilisez cette commande :
sudo apt install csvkit
Pour l’installer sur Fedora, vous devez taper :
sudo dnf install python3-csvkit
Sur Manjaro la commande est :
sudo pacman -S csvkit
Si on lui passe le nom d’un fichier CSV, le csvlook
L’utilitaire affiche un tableau montrant le contenu de chaque champ. Le contenu du champ est affiché pour montrer ce que représente le contenu du champ, et non tel qu’il est stocké dans le fichier CSV.
Essayons csvlook
avec notre fichier « sample2.csv » problématique.
csvlook sample2.csv
Tous les champs sont correctement affichés. Cela prouve que le problème n’est pas le CSV. Le problème est que nos scripts sont trop simplistes pour interpréter correctement le CSV.
Pour sélectionner des colonnes spécifiques, utilisez la csvcut
commande. Le -c
(colonne) peut être utilisée avec les noms de champ ou les numéros de colonne, ou un mélange des deux.
Supposons que nous ayons besoin d’extraire les noms et prénoms, les intitulés de poste et les adresses e-mail de chaque enregistrement, mais que nous souhaitions que l’ordre des noms soit « nom, prénom ». Tout ce que nous avons à faire est de mettre les noms ou les numéros des champs dans l’ordre dans lequel nous les voulons.
Ces trois commandes sont toutes équivalentes.
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
Nous pouvons ajouter le csvsort
commande pour trier la sortie par un champ. Nous utilisons le -c
(colonne) pour spécifier la colonne à trier, et l’option -r
(inverse) option pour trier par ordre décroissant.
csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r
Pour rendre la sortie plus jolie, nous pouvons la faire passer csvlook
.
csvcut -c 3,2,4,5 sample2.csv | csvsort -c 1 -r | csvlook
Une touche soignée est que, même si les enregistrements sont triés, la ligne d’en-tête avec les noms de champs est conservée comme première ligne. Une fois que nous sommes satisfaits d’avoir les données comme nous le voulons, nous pouvons supprimer le csvlook
à partir de la chaîne de commande, et créez un nouveau fichier CSV en redirigeant la sortie dans un fichier.
Nous avons ajouté plus de données au « sample2.file », supprimé le csvsort
et créé un nouveau fichier appelé « sample3.csv ».
csvcut -c 3,2,4,5 sample2.csv > sample3.csv
Un moyen sûr de nettoyer les données CSV
Si vous ouvrez un fichier CSV dans LibreOffice Calc, chaque champ sera placé dans une cellule. Vous pouvez utiliser la fonction Rechercher et remplacer pour rechercher des virgules. Vous pouvez les remplacer par « rien » pour qu’ils disparaissent, ou par un caractère qui n’affectera pas l’analyse CSV, comme un point-virgule « ;
» par exemple.
Vous ne verrez pas les guillemets autour des champs entre guillemets. Les seuls guillemets que vous verrez sont les guillemets intégrés à l’intérieur des données de champ. Ceux-ci sont affichés sous forme de guillemets simples. Trouver et remplacer ceux-ci par une seule apostrophe « '
” remplacera les guillemets doubles dans le fichier CSV.
Faire la recherche et le remplacement dans une application comme LibreOffice Calc signifie que vous ne pouvez pas supprimer accidentellement les virgules de séparation de champs, ni supprimer les guillemets autour des champs entre guillemets. Vous ne modifierez que les valeurs de données des champs.
Nous avons changé toutes les virgules dans les champs avec des points-virgules et tous les guillemets intégrés avec des apostrophes et avons enregistré nos modifications.
Nous avons ensuite créé un script appelé « field3.sh » pour analyser « 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)
Voyons ce que nous obtenons lorsque nous l’exécutons.
./field3.sh
Notre analyseur simple peut maintenant gérer nos enregistrements auparavant problématiques.
Vous verrez beaucoup de CSV
CSV est sans doute la chose la plus proche d’une langue commune pour les données d’application. La plupart des applications qui gèrent une certaine forme de données prennent en charge l’importation et l’exportation de fichiers CSV. Savoir comment gérer le CSV de manière réaliste et pratique vous sera très utile.