Forum Programmation.shell Trier un fichier CSV avec une boucle while read en Bash

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
1
avr.
2019

Bonjour,

J'aimerais votre aide concernant le tri de deux fichiers CSV en bash.

Tous les mois, je génère un fichier csv avec certaines informations. Je dois comparer certains éléments de ce fichier avec le fichier du mois précédent afin de voir quelles données ont changées, ce qui a été ajouté ou supprimé.

Je ne dois pas comparer l'intégralité des fichiers csv, seulement 4 colonnes des tableaux et en fonction de certaines valeurs clés. Du coup, j'utilise cette boucle :

while read jour
do
            grep -wf "$1" "$2" | awk -F',' '{if(f!=$1)print"\n"; f=$1; print $0;}' | awk -F',' '{print $1","$2","$15","$17}' > test1.csv
            grep -wf "$1" "$3" | awk -F',' '{if(f!=$1)print"\n"; f=$1; print $0;}' | awk -F',' '{print $1","$2","$15","$17}' > test2.csv
done <"$1"

J’exécute le script de cette manière :

./MonScript.sh valerus_cles.csv fichier1.csv fichier2.csv

  • {print $1","$2","$15","$17}' > me permet de récupérer uniquement les 4 colonnes qui m'intéressent.
  • Le $1 correspond au fichier " valeurs_cles.csv" que je créé au préalable avec certaines valeurs clés.

J'extrais donc toutes les lignes dans lesquelles se trouve un des mots clés présent dans le fichier " valeurs_cles.csv "je les ranges par bloques de " récurrences " puis je fusionne les deux csv avec ce commande :

paste -d, test1.csv <(echo) <(echo) test2.csv > FINAL.csv

Ça me permet d'avoir les données de test1.csv à gauche et celles de test2.csv à droite. Au moins j'ai tout sous les yeux ( en imaginant que mon fichiers contenant les valeurs clés est en fait la liste des jours de la semaine et que je cherche toutes les lignes des fichiers csv où se trouvent un de ces jours) :

Lundi XXXX XXXX XXXX     Lundi XXXX XXXX XXXX
XXXX Mardi XXXX XXXX     XXXX Mardi XXXX XXXX
XXXX XXXX Mardi XXXX     XXXX XXXX Mardi XXXX
XXXX XXXX XXXX Jeudi     XXXX XXXX Jeudi XXXX

Le problème c'est que ça fonctionne parfaitement uniquement si je retrouve les valeurs clés dans les deux fichiers csv à analyser. Si les valeurs clés ne sont pas dans le deuxième fichier, tout est décallé lors de la fusion et c'est illisible. Mais si elles ne sont pas dans le fichiers 2, c'est qu'elles ont été forcément supprimées entre le moment où j'ai généré mon fichier csv pour le mois dernier et celui pour le mois actuel et ça, ça m'intéresse !

Du coup j'aimerais savoir comment empêcher ma boucle d'extraire la ligne si la valeurs clés n'est pas présente dans le fichier 2 et comment ajouter une phrase indiquant " Valeur non trouvée : ma_valeur ".

Au final, le but serait d'avoir un fichier comme cela :

XXXX XXXX XXXX XXXX     XXXX XXXX XXXX XXXX
XXXX XXXX XXXX XXXX     XXXX XXXX XXXX XXXX
XXXX XXXX XXXX XXXX     XXXX XXXX XXXX XXXX
XXXX XXXX XXXX XXXX     XXXX XXXX XXXX XXXX

Valeur non trouvée : XXXX
Valeur non trouvée : XXXX

Merci d'avance !

  • # revoir la logique

    Posté par  . Évalué à 3.

    comparer des fichiers : diff

    comparer selon des colonnes : awk print pour ne sortir que tes colonnes et faire test1.csv et test2.csv, puis diff sur les fichiers ne contenant que les colonnes ciblées.

  • # idem

    Posté par  . Évalué à 2.

    J'ai compris le principe, pas les détails, trop de fautes.

    Même principe qu'un Message précédent
    Pendant la lecture du 2e fichier, supprimer du tableau en mémoire ce qui a été trouvé et en fin d'exécution (END{}, imprimer ce qui reste en mémoire, = pas trouvé dans le 2e fichier.)

    Bonne bourre.

  • # Join

    Posté par  . Évalué à 2.

    J’ai pas tout saisi, mais un petit man join pourra peut-être t’aider.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.