Une compilation de documentations   { en , fr }

Boucler sur les champs de ligne en awk

Étiquettes:
Créé en:
Dernière modification:
Auteur:
Xavier Béguin
Version en anglais : Loop line fields in awk

Le principe

Sous awk, si on veut effectuer une boucle sur un nombre variable de champs d'un enregistrement (qui représente généralement une ligne, les champs étant les mots séparés par des espaces), il faut de se rappeler que :

  • le nombre de champs de l'enregistrement en cours de traitement est conservé dans la variable NF ;
  • et que la valeur d'un champ peut être lu en préfixant une variable numérique par $ : si la variable i vaut 3, alors $i est équivalent à $3 et donne la valeur du troisième champ de l'enregistrement en cours.

Mise en œuvre

Exemple de données

Pour illustrer ces possibilités de awk, on va chercher à traiter un fichier texte disposant d'un nombre variable de champs sur chaque ligne, et dont le premier champ de chaque ligne représente un prénom, suivi par des nombres associés à cette personne.

Voici un exemple de tel fichier, qu'on désignera par le fichier loto.txt :

# Prénom liste_de_numéros
Philip 2 65 12 96
Turanga 55 34 82
Hubert 23
Amy 44 12 9 24
Hermes 32 99

Programme minimaliste

Dans le programme awk suivant destiné à traiter le fichier de données ci-dessus, la première ligne ignore les lignes commençant par un croisillon. Le block suivant, qui s'applique à toutes les autres lignes, affiche sur une nouvelle chacun des nombres associés à une personne, c'est à dire chacun des champs de la ligne à partir de 2 (le champ 1 étant le prénom) :

  /^#/ { next }
  {
      for (i=2; i<=NF; i++) {
          printf "%s a reçu le numéro %d\n", $1, $i
      }
  }

Utilisation du programme sur les données

Notre petit programme awk peut être utilisé depuis un interpréteur shell, comme dans l'exemple ci-dessous.

Il parcourera le fichier loto.txt, en ignorant sa première ligne puisqu'elle commence par un croisillon #, puis, pour chaque ligne suivante, il affichera sur une nouvelle ligne en sortie pour chacun des nombres associés à une personne :

$ awk '
  /^#/ { next }
  {
      for (i=2; i<=NF; i++) {
          printf "%s a reçu le numéro %d\n", $1, $i
      }
  }
  ' loto.txt
Philip a reçu le numéro 65
Philip a reçu le numéro 12
Philip a reçu le numéro 96
Turanga a reçu le numéro 55
Turanga a reçu le numéro 34
Turanga a reçu le numéro 82
Hubert a reçu le numéro 23
...