Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 09/05/2025, à 21:57

Zococo

[Résolu]Tableau associatif et boucles - perte du tableau fin boucle

Bonjour,
je lis un fichier texte à l'intérieur d'un script. C'est assez simple et je maîtrise bien l'exercice. Je renseigne donc deux tableaux associatifs nommés  tableau_occurrences_deuxieme_info et tableau_occurrences_troisieme_info. A la fin de la boucle, j'obtiens dans chacun des tableaux le nombre d’occurrences des valeurs passées en colonnes 2 et 3, les valeurs correspondant ainsi aux clés du tableau.
Voici un script parfaitement fonctionnel :

#!/bin/bash

# Initialisation
declare -A tableau_occurrences_deuxieme_info
declare -A tableau_occurrences_troisieme_info

# Lecture des informations du fichier
while IFS=$'\t' read -r premiere_info deuxieme_info troisieme_info; do 
  ((tableau_occurrences_deuxieme_info[${deuxieme_info}]++))
  ((tableau_occurrences_troisieme_info[${troisieme_info}]++))
done < "${fichier_entree}" 

# Affichage du résultat (je me limite à la colonne 2 pour ce poste déjà bien touffu mais je travaille aussi sur la 3)
echo "Occurrences uniques de la colonne 2 avec leur nombre d'apparitions :"
for occurrence in "${!tableau_occurrences_deuxieme_info[@]}";do 
  echo "$occurrence ${tableau_occurrences_deuxieme_info[$occurrence]}"; 
done

Par exemple, pour un fichier ainsi construit (séparateur tab) :

  • Paul    Banane    Bleu

  • Micheline    Pomme    Rouge

  • Arthur    Poire    Verte

  • Aline    Banane    Orange

  • André    Poire    Rose

  • Aurélie    Banane    Violette

Le résultat sera :

Occurrences uniques de la colonne 2 avec leur nombre d'apparitions :
Banane 3
Pomme 1
Poire 2

Jusqu'ici tout va bien. Mais j'ai un problème, mon fichier comporte une ligne d'en-tête que je ne souhaite pas traiter sinon les en-tête sont comptés comme des enregistrements. Le fichier est donc en fait celui-ci :

  • #Prénom    Fruit    Couleur

  • Paul    Banane    Bleu

  • Micheline    Pomme    Rouge

  • Arthur    Poire    Verte

  • Aline    Banane    Orange

  • André    Poire    Rose

  • Aurélie    Banane    Violette

J'obtiens le résultat suivant, qui ne me convient pas :

Occurrences uniques de la colonne 2 avec leur nombre d'apparitions :
Fruit 1
Banane 3
Pomme 1
Poire 2

Je suis donc allé explorer la toile et j'ai identifié deux solutions possibles. La première ne fonctionne pas. Elle consiste à placer un read -r _ < $fichier juste avant la boucle while :

read -r _ < "${fichier_entree}" 
 while IFS=$'\t' read -r premiere_info deuxieme_info troisieme_info; do 

L'idée est que le premier read lit la 1ere ligne puis la boucle while les suivantes. Chez moi échec, la boucle reprend la lecture du fichier dès le début et donc j'ai toujours le même résultat.
L'autre solution consiste à confier la lecture du fichier à tail puis à rediriger le résultat vers while par un pipe ainsi construit :

tail -n +2 "${fichier_entree}" | while IFS=$'\t' read -r premiere_info deuxieme_info troisieme_info; do 

Ce code évite de lire la première ligne, c'est bien. Malheureusement en sortie de boucle, le script perd le contenu des tableaux associatifs comme si ceux-ci étaient des variables locales à l'intérieur de la boucle. J'ai inséré des echo pour le débogage à l'intérieur du script et voici ce que j'obtiens.
Le code :

# Lecture des informations du fichier
tail -n +2 "${fichier_entree}" | while IFS=$'\t' read -r premiere_info deuxieme_info troisieme_info; do 
  ((tableau_occurrences_deuxieme_info[${deuxieme_info}]++))
  echo "Suivi : {deuxieme_info}]  ${tableau_occurrences_deuxieme_info[${deuxieme_info}]}" # AFFICHAGE POUR LE DÉBOGAGE 
done

# Verification en sortie de boucle
echo  # saut de ligne
echo "Clés :  ${!tableau_occurrences_deuxieme_info[@]}"
echo "Valeurs : ${tableau_occurrences_deuxieme_info[@]}"

Et le résultat :

Suivi : Banane 1
Suivi : Pomme 1
Suivi : Poire 1
Suivi : Banane 2
Suivi : Poire 2
Suivi : Banane 3

Clés :
Valeurs : 

Et là j'avoue ne plus rien y comprendre, sauf à se dire qu'en sortie de boucle while, le contenu du tableau tableau_occurrences_deuxieme_info est réinitialisé.
Évidemment je peux m'en sortir en ajoutant un test sur le premier caractère de chaque ligne après la lecture, du style if [[ "${premiere_info:0:1}" != "#" ]] ; then mais cela signifie faire le test à chaque tour de la boucle. Compte tenu du faible volume de mes fichiers (100 à 200 lignes) ce n'est pas très grave mais ce n'est pas très "propre".
Est-ce que quelqu'un sur le forum pourrait m'expliquer ce qui se passe ? Et éventuellement me suggérer une solution de contournement ?
Par avance merci !

Dernière modification par Zococo (Hier à 00:20)


Ubuntu 24.04 (64 bits) - Gigabyte B250M-DS3H / Core i5-7600K (Kaby lake) - Microsoft surface Go 3

Hors ligne

#2 Le 09/05/2025, à 22:57

Watael

Re : [Résolu]Tableau associatif et boucles - perte du tableau fin boucle

salut,

while IFS=$'\t' read -r premiere_info deuxieme_info troisieme_info; do 
  ((tableau_occurrences_deuxieme_info[$deuxieme_info]++))
  echo "Suivi : {deuxieme_info}]  ${tableau_occurrences_deuxieme_info[$deuxieme_info]}" # AFFICHAGE POUR LE DÉBOGAGE 
done < <(tail -n +2 "$fichier_entree" )

les accolades, sur les "variables plates", ici, ne servent à rien.

pourquoi tail | while read...Done ne permet pas d'obtenir les tableaux : parce qu'un pipeest exécuté dans un sous-shell. Or, hors d'un sous-shell, les variables qui y sont définies n'existent pas (comme dans un script par rapport au shell courant). wink


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#3 Le 09/05/2025, à 23:50

Zococo

Re : [Résolu]Tableau associatif et boucles - perte du tableau fin boucle

Bonsoir et merci,
sinon ça ne faisait vraiment pas mon affaire tout ça mais c'est clair et en plus ça correspond à ce que je ressentais confusément.
Merci pour la solution, j'avais essayé un seul < en fin de boucle, mais 2 je n'y aurais pas pensé !
Bonne soirée,


Ubuntu 24.04 (64 bits) - Gigabyte B250M-DS3H / Core i5-7600K (Kaby lake) - Microsoft surface Go 3

Hors ligne

#4 Hier à 02:35

Watael

Re : [Résolu]Tableau associatif et boucles - perte du tableau fin boucle

ce n'est pas deux <, c'est une redirection (<), et une substitution de processus (<(cmd...)).


Connected \o/
Welcome to sHell. · eval is evil.

Hors ligne

#5 Hier à 11:03

Zococo

Re : [Résolu]Tableau associatif et boucles - perte du tableau fin boucle

Merci


Ubuntu 24.04 (64 bits) - Gigabyte B250M-DS3H / Core i5-7600K (Kaby lake) - Microsoft surface Go 3

Hors ligne