Ta

Tableaux en Bash

{one: "%{count} exercice", many: "%{count} d'exercices", other: "%{count} exercices"}

À propos de Tableaux

Bash propose deux types de paramètres : les valeurs « scalaires » et les tableaux. Une valeur scalaire peut être une string ou un nombre ; elle représente une seule « chose ».

La plupart du temps, les valeurs scalaires suffisent à contenir les données. Mais il arrive que tu doives stocker une liste de valeurs scalaires. Dans ce cas, tu utiliseras un tableau.

Il existe deux sortes de tableaux :

  • Les tableaux indexés numériquement associent une clé entière à une valeur de type string. (D'autres langages parlent de « liste » ou de « séquence ».)
  • Les tableaux associatifs associent une clé de type string à une valeur de type string. (D'autres langages parlent de « map » ou de « dictionnaire ».)

Les premières sections de ce document traitent des tableaux indexés numériquement (appelés simplement « tableaux » par la suite). Les détails sur les tableaux associatifs apparaissent à la fin.

Caution

Les tableaux Bash ne peuvent stocker que des valeurs scalaires. Il est impossible de créer un tableau à deux dimensions (un tableau de tableaux).

Déclarer et initialiser une variable de type tableau

Tu peux initialiser un tableau en affectant à une variable une liste d'éléments entre parenthèses (éventuellement vide).

myarray=("one" "two" "three")

Comme pour toute affectation de variable, il ne doit y avoir aucun espace autour du signe égal.

Remarque qu'il n'y a pas de virgule entre les éléments ; c'est une liste de strings séparés par des espaces.

En fait, la quantité d'espaces à l'intérieur des parenthèses est complètement arbitraire. Les retours à la ligne sont autorisés ; utilise autant d'espaces que tu veux pour améliorer la lisibilité.

myarray=(
    "first element"
    "second element"
    "this is the last element"
)

Affecter une liste de strings à une variable tableau de cette façon place la première string à l'indice zéro, la suivante à l'indice un, la suivante à l'indice deux, et ainsi de suite.

Il est possible d'initialiser un « tableau creux » en précisant les indices dont tu as besoin.

raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
Note

Pour le rappeler : les indices d'un tableau commencent à zéro. Ce bout de code affiche true :

myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false

Tu peux utiliser la commande declare (ou local à l'intérieur d'une fonction) pour préciser qu'une variable contiendra un tableau.

declare -a myarray

Il est plus idiomatique d'affecter directement une liste entre parenthèses (éventuellement vide) pour initialiser la variable.

Accéder aux éléments d'un tableau

Comme tu l'as vu dans la note ci-dessus, la syntaxe pour accéder à un élément d'un tableau est ${myarray[$index]}. L'indice se place entre crochets. Les accolades sont obligatoires.

Note

Pour les tableaux indexés numériquement, l'indice est une expression arithmétique. Le manuel de Bash indique :

Dans une expression arithmétique, les variables du shell peuvent aussi être référencées par leur nom sans utiliser la syntaxe d'expansion de paramètre.

Cela signifie que le $ n'est pas nécessaire pour une expansion « simple » de variable. Tu peux accéder aux éléments comme ceci, ce qui est un peu plus lisible :

i=5
echo "${myarray[i]}"
# ..............^

Si l'indice donné n'existe pas dans le tableau, le résultat de l'expansion est une string vide.

Affecter une valeur à un tableau

Pour affecter une valeur à une entrée précise d'un tableau, utilise cette syntaxe :

myarray[10]="hello"

Pour ajouter un élément à un tableau, utilise l'opérateur d'affectation par concaténation +=, avec des parenthèses :

myarray+=("new element 1" "new element 2")

Parcourir un tableau

Tu auras généralement besoin de parcourir les valeurs d'un tableau. Utilise une boucle for (que tu as vue dans le concept Boucles) :

myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
    echo "$value"
done

Remarque la syntaxe spéciale pour développer le tableau : "${myarray[@]}". Cette forme d'expansion de paramètre substitue les valeurs du tableau comme des mots séparés. Elle est à peu près équivalente à :

for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"

La forme "${myarray[@]}" fonctionne avec les tableaux creux : elle ne développe que les valeurs définies.

Cette expansion spéciale, où l'indice est un arobase (@), n'est spéciale qu'entre guillemets doubles.

Autres expansions de paramètres spéciales

Voici deux autres bouts de syntaxe spéciale dont on a besoin pour parcourir un tableau. Ils sont décrits dans le manuel, à la section Expansion des paramètres du shell.

Pour connaître la longueur d'un tableau, utilise ${#myarray[@]}, avec un # avant le nom. La « longueur » d'un tableau désigne le nombre d'éléments qu'il contient.

Pour extraire la liste des indices d'un tableau, utilise "${!myarray[@]}", avec un ! avant le nom et l'expansion entre guillemets doubles. Pour les tableaux indexés numériquement, les indices sont développés dans l'ordre numérique.

Parcourir les indices d'un tableau

Parfois, tu as besoin de l'indice en plus de la valeur. Il y a plusieurs façons de faire cela.

  1. Quand tu sais que les indices forment une suite ininterrompue, tu peux utiliser une boucle for arithmétique.

    for ((i = 0; i < ${#myarray[@]}; i++)); do
        echo "$i -> ${myarray[i]}"
    done
    

    Remarque la syntaxe ${#myarray[@]}, avec le caractère # devant le nom du tableau. Comme les tableaux sont indexés à partir de zéro, le dernier indice du tableau vaut la longueur du tableau moins un.

  2. Quand le tableau est creux, tu peux utiliser cette forme :

    for index in "${!raindrops[@]}"; do
        echo "$index -> ${raindrops[index]}"
    done
    

    Remarque la syntaxe ${!myarray[@]}, avec le caractère ! devant le nom du tableau.

Inspecter un tableau

Si tu veux regarder le contenu d'un tableau, utilise la commande declare avec l'option -p :

a=("the 'first' element"
   second
   third
   'the "last" element')
declare -p a

Cela affiche le contenu avec la syntaxe de guillemets canonique du shell.

declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")

Les tableaux associatifs

Pour le rappeler, les tableaux associatifs utilisent des strings comme indices, et non des nombres. Tout ce qui précède s'applique aux tableaux associatifs, avec quelques petites différences. En général, on parle de « clé » et non d'« indice » : les tableaux associatifs associent des clés à des valeurs.

Déclarer un tableau associatif

Contrairement aux tableaux indexés, les tableaux associatifs doivent être déclarés. Utilise l'option -A de declare (ou de local dans une fonction) :

declare -A mymap

myfunc() {
    local -A my_local_map
    # ...
}

Initialiser un tableau associatif

Les paires clé-valeur sont précisées dans la liste entre parenthèses :

mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap

Cela affiche :

declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
Note

Sache que les tableaux associatifs ne sont pas ordonnés.

La déclaration et l'initialisation peuvent se faire sur une seule ligne.

declare -A mymap=([first]=foo [second]=bar [third]=baz)

Dans les versions récentes de Bash, l'initialisation peut utiliser une liste (key value key value ...).

declare -A mymap=(first foo second bar third baz)

Accéder aux valeurs

On utilise la même syntaxe que précédemment pour accéder aux éléments : ${mymap[$key]}.

Les clés d'un tableau associatif ne sont pas évaluées dans un contexte arithmétique. La syntaxe habituelle d'expansion de paramètre est nécessaire.

Affecter une valeur à un tableau associatif

L'affectation utilise la même syntaxe que précédemment :

mymap[$key]="$value"

Parcourir un tableau associatif

Tu peux utiliser une boucle for value in "${mymap[@]}" pour parcourir le tableau. Cependant, tu veux généralement aussi la clé qui va avec la valeur.

Utilise la syntaxe "${!mymap[@]}" que l'on a vue plus haut.

for key in "${!mymap[@]}"; do
    echo "$key -> ${mymap[$key]}"
done

Cela affiche

second -> bar
first -> foo
third -> baz

Pour bien insister, les clés n'ont aucun ordre.

Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet