Chapitre 12. Tableaux

Table des matières

12.1. Tableaux classiques
12.1.1. Définition et initialisation
12.1.2. Opérations sur un élément de tableau classique
12.1.3. Opérations sur un tableau classique
12.2. Tableaux associatifs
12.2.1. Définition et initialisation
12.2.2. Opérations sur un élément de tableau associatif
12.2.3. Opérations sur un tableau associatif

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.

12.1. Tableaux classiques

12.1.1. Définition et initialisation

  • 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='()'
    declare -a BASH_ARGV='()'
    declare -a BASH_LINENO='()'
    declare -a BASH_SOURCE='()'
    declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="24" [3]="1" [4]="release" [5]="i686-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.

    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")'
    $

12.1.2. Opérations sur un élément de tableau classique

  • 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
      $

    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 : ${#nomtab[indice]}

    $ echo ${tabmess[0]}
    bonjour
    $
    $ echo ${#tabmess[0]}
    7   => longueur de la chaîne bonjour
    $
  • 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.

    Suppression d’une sous-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}

    Substitution 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]#*:}
    18:1,83
    $
    $ echo ${tpers[0]^^}
    JEAN FONTAINE:20:1,72
    $

12.1.3. Opérations sur un tableau classique

  • Nombre d’éléments d’un tableau classique : ${#nomtab[@]}

    Parmi les différentes notations possibles pour connaître le nombre d’éléments d’un tableau classique, on utilisera celle-ci : ${#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[@]}")

    $ tab=("un 1"  "deux 2"  "trois 3")
    $ 
    $ tab+=("quatre 4" fin)		=>  ajout de plusieurs éléments en fin de tableau
    $ 
    $ echo "${tab[@]}"
    un 1 deux 2 trois 3 quatre 4 fin
    $ 
    $ tab=(debut "zero 0" "${tab[@]}")		=> ajout de plusieurs é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
    $
  • Suppression d’un tableau classique

    Pour supprimer un ou plusieurs tableaux classiques : unset nomtab ...

    $ unset tabcopy  tab
    $