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 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.
Les tableaux Bash ne peuvent stocker que des valeurs scalaires. Il est impossible de créer un tableau à deux dimensions (un tableau de tableaux).
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")
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.
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.
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.
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")
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.
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.
Parfois, tu as besoin de l'indice en plus de la valeur. Il y a plusieurs façons de faire cela.
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.
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.
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")
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.
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
# ...
}
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")
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)
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.
L'affectation utilise la même syntaxe que précédemment :
mymap[$key]="$value"
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.