Mes documentations

« Retour à l'accueil

Introduction aux tableaux en bash

Date de rédaction: octobre 2014
Dernière modification: août 2015

L’interpréteur bash permet d’utiliser des tableaux indicés ou associatifs. Ce document présente les opérations de base de leur utilisation.

Ces tableaux peuvent paraître un peu déconcertants au début en raison d’une syntaxe un peu particulière, et leur utilisation peut générer quelques problèmes difficiles à pister en raison du manque d’erreurs rapportées par l’interpréteur, mais ce sont tout de même des outils bien pratiques dans des scripts shell un peu avancés.

Sommaire

  1. Création d’un tableau
  2. Affichage du tableau
  3. Lecture d’un élément
  4. Modification d’un élément
  5. Affichage de la liste des clefs
  6. Obtention de la taille d’un tableau
  7. Destruction d’un élément de tableau
  8. Destruction d’un tableau entier
  9. Pour en savoir plus

1. Création d’un tableau

La création d’un tableau indicé peut se faire simplement par initialisation, en fournissant ses élements entre parenthèses :

$ tableau_indi=( "un" "deux" "trois" "quatre" )

Les indices sont ici assignés automatiquement, en commençant par 0. On peut aussi l’initialiser avec des indices imposés :

$ tableau_indi=( "fry" "leela" [42]="bender" "flexo" )

Dans cet exemple, l’indice 0 vaut fry, le 1 leela, le 42 bender et le 43 flexo (les valeurs des autres indices sont la chaîne vide).

Les tableaux associatifs peuvent être créés de la même manière, mais une clef doit bien sûr être précisée pour chaque élément :

$ tableau_asso=( ['un']="one" ['deux']="two" ['trois']="three" )

Attention : l’initialisation d’un tableau ne change pas sa nature. S’il a été créé en tant que tableau indicé, puis initialisé comme un tableau associatif de même nom, cette nouvelle initialisation ne provoquera pas d’erreur, mais le tableau sera toujours considéré comme indicé, et non associatif, et il ne se comportera pas comme vous pourriez vous y attendre. Une déclaration explicite, présentée ci-dessous, évite ce problème.

Un tableau peut être créé de façon explicite à l’aide du mot-clef declare, suivi de l’option -a pour un tableau indicé, et -A pour un tableau associatif :

$ declare -a tableau_indi
$ declare -A tableau_asso

Le tableau peut aussi être initialisé en même temps :

$ declare -a tableau_indi=( "un" "deux" "trois" "quatre" )
$ declare -A tableau_asso=( ['un']="one" ['deux']="two" ['trois']="three" )

Un tableau indicé peut également être créé en assignant une valeur à un élément indicé (voir plus bas).

Les tableaux peuvent aussi être déclarés en lecture seule grâce au mot-clef « readonly », de manière similaire à « declare » :

$ readonly -a tableau_indi_ro=( "un" "deux" "trois" "quatre" )
$ readonly -A tableau_asso_ro=( ['un']="one" ['deux']="two" ['trois']="three" )

La modification d’un tableau en lecture seule provoquera une erreur avec le message « variable en lecture seule ».

2. Affichage du tableau

L’affichage de l’ensemble d’un tableau se fait avec la syntaxe « ${montableau[*]} », ou « ${montableau[@]} ».

La différence entre l’utilisation de @ et * est identique à celle entre les variables spéciales $@ et $* du shell. Pour citer le manuel de bash :

« (…) entre guillemets doubles, ${nom[*]} se développe en un seul mot contenant les valeurs de chaque élément du tableau séparées par le premier caractère de la variable spéciale IFS et ${nom[@]} développe chaque élément de nom en un mot distinct. »

$ declare -a tableau_indi=( "un" "deux" "trois" "quatre" )
$ echo ${tableau_indi[@]}
un deux trois quatre

$ declare -A tableau_asso=( ['un']="one" ['deux']="two" ['trois']="three" )
$ echo ${tableau_asso[@]}
one two three

L’utilisation des accolades est nécessaire pour éviter les conflits avec les développements de chemin (dans lesquels les crochets ont une signification spéciale).

3. Lecture d’un élément

La lecture d’un élément se fait selon la syntaxe tableau[indice], mais nécessite toujours les accolades :

$ montableau=("un" "deux" "trois" "quatre")
$ echo ${montableau[2]}
trois

$ declare -A tab_asso=( ['un']="one" ['deux']="two" ['trois']="three" )
$ echo ${tab_asso["deux"]}
two

Pour les tableaux indicés, un indice négatif correspond à un indice commençant à l’indice maximal du tableau plus un (le dernier élément est donc -1).

$ tableau_indi=( "fry" "leela" [42]="bender" "zoidberg" "flexo" )
$ echo "Why not ${tableau_indi[-2]} ?"
Why not zoidberg ?

Attention, si aucun indice n’est fourni pour le tableau, on accède à l’indice 0 :

$ montableau=( "un" "deux" "trois" "quatre" )
$ echo $montableau
un

4. Modification d’un élément

Un élément peut être assigné selon la syntaxe tableau[indice]=valeur. Si le tableau n’existe pas, il sera créé comme un tableau indicé :

$ tab[1]="uno"
$ echo ${tab[1]}
uno

Il n’est pas possible de créer un tableau associatif en lui assignant un élément, il faut le déclarer explicitement avant l’assignation (ou l’initialiser en lui fournissant les clefs entre crochets, comme décrit dans « création d’un tableau ») :

$ declare -A tab_asso
$ tab_asso["couleur"]="jaune"
echo ${tab_asso["couleur"]}
jaune

Si le tableau est en lecture seule, cette opération génère une erreur :

$ tableau_indi_ro[42]="h2g2"
bash: tableau_indi_ro : variable en lecture seule

5. Affichage de la liste des clefs

Il est possible d’obtenir la liste des clefs d’un tableau à l’aide de la syntaxe ${!tableau[@]}. Dans le cas d’un tableau indicé, on obtient ses indices :

$ declare -a tableau_indi=( "un" "deux" "trois" "quatre" )
$ echo ${!tableau_indi[@]}
0 1 2 3

$ declare -A tableau_asso=( ['un']="one" ['deux']="two" ['trois']="three" )
$ echo ${!tableau_asso[@]}
un deux trois

Ceci permet de vérifier les indices assignés aux valeurs lors de l’initialisation du tableau :

$ declare -a tableau_indi( "fry" "leela" [42]="bender" "flexo" )
$ echo ${!tableau_indi[@]}
0 1 42 43

6. Obtention de la taille d’un tableau

Le nombre d’éléments contenus dans un tableau (donc sa taille) s’obtient avec la syntaxe ${#tableau[@]} :

$ declare -a tableau_indi=( "un" "deux" "trois" "quatre" )
$ echo ${#tableau_indi[@]}
4

$ declare -A tableau_asso=( ['un']="one" ['deux']="two" ['trois']="three" )
$ echo ${#tableau_asso[@]}
3

Attention, les indices pouvant être choisis, sa taille ne correspond pas forcément au plus grand indice augmenté de un :

$ declare -a tableau_indi( "fry" "leela" [42]="bender" "flexo" )
$ echo ${#tableau_indi[@]}
4

7. Destruction d’un élément de tableau

On peut supprimer un élément d’un tableau avec la commande interne unset tableau[indice] :

$ declare -a tableau_indi=( "un" "deux" "trois" "quatre" )
$ echo ${tableau_indi[@]}
un deux trois quatre
$ unset tableau_indi[1]
$ echo ${!tableau_indi[@]}
0 2 3
$ echo ${tableau_indi[@]}
un trois quatre

$ declare -A tableau_asso=( ['un']="one" ['deux']="two" ['trois']="three" )
$ echo ${tableau_asso[@]}
one two three
$ unset tableau_asso['deux']
$ echo ${!tableau_asso[@]}
un trois
$ echo ${tableau_asso[@]}
one three

8. Destruction d’un tableau entier

La commande unset permet aussi de détruire tout un tableau, en lui passant son nom, nom[*] ou nom[@]. Ainsi, en supposant un tableau de nom tableau, les trois lignes suivantes sont équivalentes :

Par exemple :

$ declare -a tableau_indi=( "un" "deux" "trois" "quatre" )
$ unset tableau_indi
$ echo ${!tableau_indi[@]}
 

3. Pour en savoir plus

Dernières modifications de ce document