Table des matières
Moins utilisés que les chaînes de caractères ou les entiers, bash intègre les tableaux classiques et les tableaux associatifs. Les éléments des premiers sont indicés par des entiers, tandis que les éléments des seconds sont indexés par des chaînes de caractères.
Les tableaux classiques et associatifs sont monodimensionnels. Il n'y a pas de taille maximale fixée pour un tableau
Pour créer un ou plusieurs tableau classiques vides, on utilise généralement l'option -a de la commande interne declare :
declare -a nomtab ...
Le tableau nomtab est simplement créé mais ne contient aucune valeur : le tableau est défini mais n'est pas initialisé.
Pour lister les tableaux classiques définis : declare -a
declare -a BASH_ARGC=([0]="0") declare -a BASH_ARGV=() declare -a BASH_COMPLETION_VERSINFO=([0]="2" [1]="11") declare -a BASH_LINENO=() declare -a BASH_REMATCH=() declare -a BASH_SOURCE=() declare -ar BASH_VERSINFO=([0]="5" [1]="1" [2]="4" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu") declare -a DIRSTACK=() declare -a FUNCNAME declare -a GROUPS=() declare -a PIPESTATUS=([0]="0") $
Pour désigner un élément d'un tableau classique, on utilise la syntaxe : nomtab[indice]
$ declare -a tab => définition du tableau tab $ $ read tab[1] tab[3] coucou bonjour $ $ tab[0]=hello $
Pour définir et initialiser un tableau classique : declare -a nomtab=( val0 val1 ... )
Comme en langage C, l'indice d'un tableau classique débute toujours à 0 et sa valeur maximale est celle du plus grand entier positif représentable dans ce langage (bash a été écrit en C). L'indice peut être une expression arithmétique [cf. Chapitre 11, Entiers et expressions arithmétiques].
Il n'est pas obligatoire d’utiliser la commande interne declare pour créer un tableau classique, il suffit d'initialiser un de ses éléments :
$ array[3]=bonsoir => création du tableau array avec $ => initialisation de l’élément d’indice 3
Trois autres syntaxes sont également utilisables pour initialiser globalement un tableau classique :
nomtab=(val0 val1 ...)
nomtab=( [indice]=val ... )
$ arr=([1]=coucou [3]=hello) $
l'option -a de la commande interne read ou readonly. Chaque mot saisi devient un élément du tableau classique :
$ read -a tabmess bonjour tout le monde $
Pour créer un tableau classique en lecture seule, on utilise les options –ra.
$ declare -ra tabconst=( bonjour coucou salut ) => tableau en lecture seule $ $ tabconst[1]=ciao bash: tabconst : variable en lecture seule $
Pour afficher les valeurs et attributs d’un tableau classique, on utilise la syntaxe : declare –p tab …
$ declare -p tabconst declare -ar tabconst=([0]="bonjour" [1]="coucou" [2]="salut") $
Valeur d'un élément d'un tableau :
On obtient la valeur d'un élément d'un tableau à l’aide la syntaxe : ${nomtab[indice]}
bash calcule d'abord la valeur de l'indice puis l'élément du tableau est remplacé par sa valeur.
Il est possible d'utiliser :
toute expression arithmétique valide de la commande interne (( pour calculer l'indice d'un élément
$ echo ${tabmess[1]} tout $ $ echo ${tabmess[RANDOM%4]} => ou bien : ${tabmess[$((RANDOM%4))]} monde $ $ echo ${tabmess[1**2+1]} le $
une variable contenant un entier
$ a=3 $ echo ${tabmess[a]} monde $
Il est possible d'utiliser une valeur négative comme indice : dans ce cas, la valeur -1 permettra d’accéder au dernier élément du tableau, la valeur -2 à l’avant-dernier élément, etc.
$ declare -p tabmess declare -a tabmess=([0]="bonjour" [1]="tout" [2]="le" [3]="monde") $ $ echo ${tabmess[-1]} monde $ $ echo ${tabmess[-4]} bonjour $ $ echo ${tabmess[-5]} bash: tabmess: mauvais indice de tableau $
Lorsqu'un nom de tableau est présent sans indice dans une chaîne de caractères ou une expression, bash l’interprète comme élément d'indice 0.
$ echo $tabmess bonjour $
Réciproquement, une variable non préalablement définie comme tableau peut être interprétée comme un tableau classique.
$ var=bonjour $ echo ${var[0]} => var est interprétée comme un tableau à un seul élément bonjour => d’indice 0 $ var=( coucou "${var[0]}" ) $ echo ${var[1]} => var est devenu un véritable tableau bonjour $
Longueur d'un élément :
Pour obtenir la longueur d'un élément d'un tableau classique : ${#nomtab[indice]}
$ declare -p tabmess declare -a tabmess=([0]="bonjour" [1]="tout" [2]="le" [3]="monde") $ $ echo ${tabmess[0]} bonjour $ $ echo ${#tabmess[0]} 7 => longueur de la chaîne bonjour $ $ echo ${tabmess[-1]} : ${#tabmess[-1]} monde : 5 => longueur du dernier élément de tabmess (chaine monde) $
Suppression d’un élément :
Suppression d'un ou plusieurs éléments d'un tableau classique : unset nomtab[indice] ...
Autres opérations :
Les différents traitements sur les chaînes de caractères vus précédemment [cf. Chapitre 9, Chaînes de caractères § 3, 4, 5, 6] sont également applicables aux éléments d’un tableau classique.
Modificateurs de chaîne :
${nomtab[indice]#modèle} ${nomtab[indice]##modèle}
${nomtab[indice]%modèle} ${nomtab[indice]%%modèle}
Extraction d’une sous-chaîne :
${nomtab[indice]:ind} ${nomtab[indice]:ind:nb}
Remplacement de sous-chaîne :
${nomtab[indice]/mod/ch} ${nomtab[indice]//mod/ch}
Transformation majuscules/minuscules :
${nomtab[indice]^^} ${nomtab[indice],,}
$ tpers=("Jean Fontaine:20:1,72" "Pierre Cascade:18:1,83") $ $ echo ${tpers[1]#*:} => Modificateur 18:1,83 $ $ echo ${tpers[0]%%:*} => Modificateur Jean Fontaine $ $ echo ${tpers[1]:0:8} => Extraction Pierre C $ $ echo ${tpers[0]/20/31} => Remplacement Jean Fontaine:31:1,72 $ $ echo ${tpers[0]/#72/91} => Remplacement si 72 est en début de chaine Jean Fontaine:20:1,72 => Aucun remplacement effectué ! $ $ echo ${tpers[0]/%72/91} => Remplacement si 72 est en fin de chaine Jean Fontaine:20:1,91 => Remplacement effectué ! $ $ echo ${tpers[0]^^} => Mise en majuscules JEAN FONTAINE:20:1,72 $
Remarque : Les syntaxes relatives à l’extraction de sous-chaines (${nomtab[indice]:ind}, ${nomtab[indice]:ind:nb}) autorisent une valeur négative pour ind. Dans ce cas, il est impératif de placer un caractère espace entre le caractère : et le caractère – désignant le signe, sous peine d’obtenir un résultat erroné.
$ echo ${tpers[0]: -4:4} => caractère espace entre : et -4 1,72 $
Dans l’exemple ci-dessus, on souhaite afficher les quatre derniers caractères de la chaine contenue dans tpers[0].
Nombre d’éléments d’un tableau classique : ${#nomtab[@]}
Il existe plusieurs notations pour connaître le nombre d’éléments d’un tableau : ${#nomtab[*]}, ${#nomtab[@]},"${#nomtab[*]}", "${#nomtab[@]".
Par souci d’homogénéité avec les syntaxes relatives aux autres opérations, nous utiliserons la notation : ${#nomtab[@]}
Il est à noter que seuls les éléments initialisés sont comptés.
$ arr=([1]=coucou [3]=hello) $ echo ${#arr[@]} 2 $
Accès à tous les éléments d’un tableau classique : "${nomtab[@]}"
Comme pour "$@" et "$*" [cf. Chapitre 2, Substitution de paramètres § 2.5], les syntaxes "${nomtab[*]}" et "${nomtab[@]}" n’ont pas la même signification pour le shell :
"${nomtab[*]}" sera remplacée par l’ensemble des éléments du tableau classique nomtab, concaténés en une seule chaîne et séparés par le premier caractère de IFS : "val0 val1 ... "
"${nomtab[@]}" sera remplacée par autant de chaînes qu’il y a d’éléments : "val0" "val1" ...
$ tabPays=("Etats Unis" France) $ $ set "${tabPays[*]}" $ echo $# 1 => une seule chaîne $ $ echo $1 Etats Unis France $ $ set "${tabPays[@]}" $ echo $# 2 => deux chaînes $ $ echo $1 Etats Unis $ echo $2 France $
Lorsque les éléments sont de simples chaînes constituées d’un seul mot, il n’y a aucune difficulté pour préserver l’intégrité de celles-ci. Cela est différent avec des chaînes composées.
$ for p in ${tabPays[*]} > do > echo $p > done Etats => l’intégrité du premier élément est rompue Unis France $
Pour préserver l’intégrité de chaque élément, il est préférable d’utiliser la syntaxe : "${nomtab[@]}"
$ for p in "${tabPays[@]}" > do > echo $p > done Etats Unis => l’intégrité du premier élément est préservée France $
Liste de tous les indices définis : "${!nomtab[@]}"
Il existe également plusieurs syntaxes pour obtenir la liste de tous les indices conduisant à un élément défini d’un tableau classique. Afin d’utiliser une syntaxe commune avec les tableaux associatifs, on utilisera la notation : "${!nomtab[@]}"
$ arr=([1]=coucou bonjour [5]=hello) $ $ echo "${!arr[@]}" 1 2 5 => pour affecter un indice à bonjour, bash a incrémenté l’indice $ => de l’élément précédent
L’intérêt d’utiliser cette syntaxe est qu’elle permet de ne traiter que les éléments définis d’un tableau « à trous ».
$ for i in "${!arr[@]}" > do > echo "$i => ${arr[i]}" => dans l’expression ${arr[i]}, bash interprète > done => directement i comme un entier 1 => coucou 2 => bonjour 5 => hello $
Copie d’un tableau classique
Pour copier un tableau classique tab : tabcopie=( "${tab[@]}" )
$ tabcopy=( "${tabPays[@]}" ) $ $ echo "${tabcopy[@]}" Etats Unis France $
Ajout d’éléments à un tableau classique
Pour ajouter un ou plusieurs éléments à un tableau classique tab :
à la fin : tab+=( val1 val2 … )
en tête : tab=( val0 val1 … "${tab[@]}")
Remarque : Si le tableau est « sans trou », il est possible d’utiliser la syntaxe suivante pour ajouter un élément val à la fin du tableau : tab[${#tab[@]}]=val
$ tab=("un 1" "deux 2" "trois 3") $ $ tab+=("quatre 4" fin) => ajout de deux éléments en fin de tableau $ $ echo "${tab[@]}" un 1 deux 2 trois 3 quatre 4 fin $ $ tab=(debut "zero 0" "${tab[@]}") => ajout de deux éléments en $ => tête de tableau $ echo ${#tab[@]} 7 => nombre d’éléments du tableau $ echo "${tab[@]}" debut zero 0 un 1 deux 2 trois 3 quatre 4 fin $ $ echo ${tab[5]} quatre 4 $
Traitement uniforme des éléments d'un tableau classique
Les opérations présentées précédemment peuvent être appliquées en une seule passe à l’ensemble des éléments d’un tableau classique.
$ tpers=("Jean Fontaine:20:1,72" "Pierre Cascade:18:1,83" "Pierre Ruisseau:17:1,68") $ $ echo ${tpers[@]##*:} 1,72 1,83 1,68 $ $ echo ${tpers[@]//:/::} Jean Fontaine::20::1,72 Pierre Cascade::18::1,83 Pierre Ruisseau::17::1,68 $ $ echo ${tpers[@]/Pierre*/} => suppression des personnes ayant Pierre comme Jean Fontaine:20:1,72 => prénom $ $ echo ${tpers[@]^^} JEAN FONTAINE:20:1,72 PIERRE CASCADE:18:1,83 PIERRE RUISSEAU:17:1,68 $ $ tab=(zero un deux trois "quatre 4" cinq six) $ $ echo ${tab[@]:2:4} => extraction de quatre éléments à deux trois quatre 4 cinq => partir de l’indice 2 inclus $ $ echo ${tab[@]: -4:2} => extraction du quatrième élément avant la fin (trois) trois quatre 4 => et du troisième élément avant la fin (quatre 4) $ => il y a un caractère espace entre : et -4
Suppression d’un tableau classique
Pour supprimer un ou plusieurs tableaux classiques : unset nomtab ...
$ unset tabcopy tab $