Bonjour, Bash permet de stocker et de manipuler simplement et nativement des tableaux de tableaux (indicés, associatifs, hybrides), et même récursivement des tableaux de tableaux de tableaux etc. C'est important, par exemple ça simplifie beaucoup la manipulation d'objets plus évolués comme les listes ou les arbres.

Cette possibilité est restée méconnue à cause d'une difficulté liée à l'affectation : Bash ne permet pas d'affecter directement un tableau T comme 'valeur' d'un autre tableau, on ne peut pas écrire par exemple t[2]=$T. Pour pallier à ce manque, une fonction "tableau" a été ajoutée (voir script ci-dessous), et l'écriture de l'affectation devient :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
t[2]=$(tableau T)   # stockage dans t[2] du tableau T
Pour retrouver ces valeurs (qui sont des tableaux), il faut utiliser des variables déclarées (même pour les tableaux indicés) dont l'affectation doit se faire au moment de la déclaration. Avec notre exemple :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
declare -a X=${t[2]}   # récupération dans le tableau X du tableau stocké dans t[2] ; utiliser "-A" si t[2] est un tableau associatif
Le script suivant montre différents cas d'utilisation. Pour se convaincre que Bash gère bien 'nativement' les tableaux de tableaux, il faut regarder comment il les stocke. Par exemple, il est possible de visualiser le tableau k (qui est un tableau de tableaux de tableaux) en dé-commentant la ligne 82.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# Tableaux de tableaux en Bash
# ============================
 
# Le Bash gère 2 types de tabeaux :
 
# 1 - les tableaux indicés (leur déclaration n'est pas obligatoire)
a=(1 2 "u v" 3)                          # ou :   declare -a a=(1 2 "u v" 3)
b=(4 5 "w x")
 
# 2 - les tableaux associatifs (leur déclaration est obligatoire)
declare -A e=([x]="iks" [y]="i grec")    # ou :   e[x]="iks" ; e[y]="i grec"
declare -A f=([un]="one" [deux]="two")
 
# Affichage d'un tableau $1 avec la même forme que quand on l'affecte globalement
# -------------------------------------------------------------------------------
tableau () { declare -p $1 \
           | awk '{typ=substr($0,10,1) ;                          # a=indicé A=associatif
                   sub("^[^=]*=.","",$0) ; sub(".$","",$0)        # suppression du "declare ..." et des quotes
                   if (typ=="a") gsub("\\[[^\\]]*\\]=","",$0) ;   # si indicé, suppression des index
                   print $0
                  }' 
           }
 
echo
echo "0 - Test de la fonction tableau"
echo "-------------------------------"
tableau a ; tableau b
tableau e ; tableau f
 
echo
echo "1 - Tableaux indices de tableaux indices"
echo "----------------------------------------"
 
c[0]=$(tableau a) 
c[1]=$(tableau b)  # on peut aussi ecrire directement   c=("$(tableau a)" "$(tableau b)"
 
# Lecture de la 2eme valeur (donc un tableau indicé) 
declare -a d=${c[1]}
# d=${c[1]}  ne marche jamais, meme s'il y a un "declare -a d" préalable
 
# Lecture des valeurs de ce tableau
echo d0= ${d[0]}
echo d1= ${d[1]}
echo d2= ${d[2]}
 
echo
echo "2 - Tableaux indices de tableaux associatifs"
echo "--------------------------------------------"
 
g[0]=$(tableau e)
g[1]=$(tableau f)
 
# Lecture de la 2eme valeur (donc un tableau associatif) 
declare -A h=${g[1]}
 
# Lecture des valeurs de ce tableau
echo ${h[un]}
echo ${h[deux]}
 
echo
echo "3 - Tableaux associatifs de tableaux associatifs"
echo "------------------------------------------------"
 
declare -A i
i[alpha]=$(tableau e)
i[beta]=$(tableau f)
 
# Dans ce tableau de tableaux, lecture de la 2eme valeur (donc un tableau associatif) 
declare -A j=${i[beta]}
 
# Lecture des valeurs de ce tableau
echo ${j[un]}
echo ${j[deux]}
 
echo
echo "4 - Tableaux associatifs de tableaux associatifs de tableaux associatifs"
echo "------------------------------------------------------------------------"
 
declare -A k
k[premier]=$(tableau i)
k[second]=$(tableau j)
# tableau k
 
# Dans ce tableau de tableaux de tableaux, lecture de la 1ère valeur (donc un tableau de tableaux)
declare -A l=${k[premier]}
 
# Puis dans cette valeur, lecture de la 2ème valeur (donc un tableau associatif)
declare -A m=${l[beta]}
 
# Lecture des valeurs de ce tableau associatif
echo ${m[un]}
echo ${m[deux]}
Cordialement