Vous êtes sur la page 1sur 30

Les tableaux sous bash

Objectifs

1ère chose à faire : consulter la page web ou équivalent


http://www.ixany.org/docs/Shell_Les_tableaux_en_bash.html

2ème chose à faire : écrire des scripts qui permettent de


1) déclarer un tableau et de le garnir
2) parcourir un tableau pour afficher son contenu
3) compter et d'afficher le nombre d'occurrences d'un élément
donné dans un tableau

3ème chose à faire : trier les données d'un tableau selon l'algorithme
tri à bulles (https://fr.wikipedia.org/wiki/Tri_%C3%A0_bulles)
Cours
Tableaux sous bash
Création d’un tableau
La création d’un tableau indicé peut se faire
simplement par initialisation, en fournissant ses
éléments 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).
Création d’un tableau associatif
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 :
tabl_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.
Déclaration d’un tableau
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 tab_indi=( "un" "deux" "trois" "quatre" )
declare -A tab_asso=( ['un']="one" ['deux']="two" )
Tableau en lecture uniquement
Les tableaux peuvent aussi être déclarés en lecture
seule grâce au mot-clef « readonly », de manière
similaire à « declare » :
readonly -a tab_ind_ro=( "un" "deux" "trois" )
readonly -A tab_ass_ro=( ['un']="one" ['deux']="two" )

La modification d’un tableau en lecture seule


provoquera une erreur avec le message « variable
en lecture seule ».
Affichage d’un tableau
L’affichage de l’ensemble d’un tableau se fait avec la syntaxe
« ${montableau[*]} », ou « ${montableau[@]} ».

$ 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).
Lecture d’un élément d’un tableau
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
Lecture d’un élément d’un tableau
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
Modification d’un élément du tableau
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) :
$ declare -A tab_asso
$ tab_asso["couleur"]="jaune"
$ echo ${tab_asso["couleur"]}
jaune
Affichage
de la liste des clefs d’un tableau
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")
$ echo ${!tableau_indi[@]}
0 1 2
Dans le cas d’un tableau associatif, on obtient ses index :
$ declare -A tabl_asso=( ['un']="one" ['deux']="two" ['trois']="three" )
$ echo ${!tabl_asso[@]}
un deux trois
Affichage
de la liste des clefs d’un tableau
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
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
Obtention de la taille d’un tableau
Attention:
les indices pouvant être choisis, la taille du
tableau ne correspond pas forcément au plus
grand indice augmenté de un :

$ declare -a tab_ind( "fry" "lela" [42]="ben" "fleo" )


$ echo ${#tab_ind[@]}
4
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 23
$ 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
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 :

unset tableau
unset tableau[@]
unset tableau[*]
Parcours d’un tableau
Pour parcourir et traiter tout un tableau, on peut recourir à un boucle for
en utilisant la notation tab[*]:

for mot in ${tab[*]}


do
echo $mot
done

ou, en utilisant les index des éléments :

for index in "${!tab[@]}"


do
echo "$index = ${tab[index]}"
done
Chercher un élément
• Chercher un élément dans le tableau :
VAR="toto"
for BLA in "${tab[@]}"
do
[[ "$VAR" == "$BLA" ]] && echo "$VAR présent"
done

• Connaitre l’index d’un élément :


for i in "${!tab[@]}"
do if [[ "${tab[$i]}" = "${value}" ]]
then echo "${i}"
fi
done
Copier un tableau
• Copier tout le tab1 dans tab2 :
tab2=("${tab1[@]}")

• Concaténer tab1 et tab2 dans tab3:


tab3=("${tab1[@]}" "${tab2[@]}")
Convertir un fichier en tableau
Pour convertir un fichier en tableau on peut
recourir à la commande « mapfile »
mapfile -t monTableau < fichier

ou utiliser la commande « cat »


monTableau=( `cat "fichier" `)
Ceci permet de transposer chaque ligne du fichier
dans un indice de monTableau
${foo[@]} vs. "${foo[@]}"
Si les éléments du tableau contiennent des espaces et séparés par des
espaces !!!, il faut utiliser les doubles quotes pour traiter chaque élément
comme élément séparé :
Ainsi :
foo=("le 1er" "le 2d"); for i in "${foo[@]}" ; do echo $i ; done
renvoie :
le 1er
le 2d

Contrairement à :
foo=("le 1er" "le 2d"); for i in ${foo[@]} ; do echo $i ; done
renvoie :
le
1er
le
2d
TPs
Tableaux sous bash
TAF : Affichage répertoire
Créer un script qui renvoie la même sortie que
la commande ls mais dans l'ordre décroissant
(autrement dit : le script devra lister le contenu
d'un répertoire dans l'ordre décroissant).

Attention :
Vous ne devez ni vous servir de la
commande ls, ni de la commande sort.
TAF : Affichage répertoire
#!/bin/bash
# Si on a au moins un paramètre
# et que le premier paramètre est un répertoire
if [ "$#" -ge 1 ] && [ -d "$1" ]
then
#aller dans le répertoire indiqué
cd $1
#construire un tableau avec tous les noms de fichiers du répertoire courant
nb=0
for fichier in *
do tab[$nb]="$fichier"
let nb=$nb+1
done
# affichage inversé
for (( i=$nb ; i>=0 ; i=$i-1 ))
do echo ${tab[$i]}
done
#retour au répertoire précédent
cd -
else echo ERREUR: nb argument ou répertoire inexistant
fi
TAF : Tri d’un tableau
Créer un script qui devra :
- enregistrer à l'aide d'un tableau, un nombre
d'entiers donné en paramètre (ou en saisie)
- puis trier ceux-ci dans l'ordre croissant dans ce
même tableau (sans passer par un autre)
- et enfin afficher le contenu du tableau
(ordonné) sur la sortie standard.
Script : Tri à bulles
#!/bin/bash
if [ "$#" -lt 1 ]
then read -p "Saisir le nombre d'éléments à ordonner : " SIZE
else SIZE=$1
fi
echo "Saisir les éléments :"
for (( i=0 ; i<SIZE ; i++ ))
do read val; tab[i]=$val
done
for (( i=0 ; i<SIZE ; i++ ))
do for (( j=$i+1 ; j<SIZE ; j++ ))
do if [ "${tab[$j]}" -le "${tab[$i]}" ]
then tampon="${tab[$i]}"
tab[$i]="${tab[$j]}"
tab[$j]="$tampon"
fi
done
done
echo "Valeurs ordonnées :"
for (( i=0 ; i<SIZE ; i++ ))
do echo "${tab[$i]}"
done
Exercice 1
Que réalise ce script bash ?

#!/bin/bash
listing=( * )
for (( i=${#listing[@]}-1 ; i >= 0 ; i=i-1 ))
do
echo ${listing[$i]}
done
Exercice 2
Que réalise ce script bash ?
#!/bin/bash
read -rp 'Entrez le nom du répertoire : ' repertoire
if [ -d "$repertoire" ]
then
if test $repertoire="/"
then fichiers= ( /* )
else fichiers=( ${repertoire}/* )
fi
((${#fichiers[@]})) && {
for (( x=${#fichiers[@]}-1; x>=0; x-- ))
do echo "${fichiers[x]}"
done
} || echo "$repertoire est vide"
else
echo "$repertoire n'est pas un répertoire"
fi
Les tableaux sous bash

Vous aimerez peut-être aussi