Coques avec tableaux associatifs
Certains shells modernes fournissent des tableaux associatifs: ksh93, bash ≥4, zsh. Dans ksh93 et bash, si a
est un tableau associatif, alors "${!a[@]}"
est le tableau de ses clés:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
Dans zsh, cette syntaxe ne fonctionne qu'en mode d'émulation ksh. Sinon, vous devez utiliser la syntaxe native de zsh:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
${(k)a}
fonctionne également si a
n'a pas de clé vide.
Dans zsh, vous pouvez également faire une boucle sur k
eys et v
alues en même temps:
for k v ("${(@kv)a}") echo "$k -> $v"
Coques sans tableaux associatifs
Émuler des tableaux associatifs dans des shells qui n'en ont pas représente beaucoup plus de travail. Si vous avez besoin de tableaux associatifs, il est probablement temps d'apporter un outil plus gros, tel que ksh93 ou Perl.
Si vous avez besoin de tableaux associatifs dans un simple shell POSIX, voici un moyen de les simuler, lorsque les clés sont restreintes pour ne contenir que les caractères 0-9A-Z_a-z
(chiffres ASCII, lettres et tiret bas). Dans cette hypothèse, les clés peuvent être utilisées dans le cadre des noms de variables. Les fonctions ci-dessous agissent sur un tableau identifié par un préfixe de dénomination, la «tige», qui ne doit pas contenir deux traits de soulignement consécutifs.
## ainit STEM
## Declare an empty associative array named STEM.
ainit () {
eval "__aa__${1}=' '"
}
## akeys STEM
## List the keys in the associatve array named STEM.
akeys () {
eval "echo \"\$__aa__${1}\""
}
## aget STEM KEY VAR
## Set VAR to the value of KEY in the associative array named STEM.
## If KEY is not present, unset VAR.
aget () {
eval "unset $3
case \$__aa__${1} in
*\" $2 \"*) $3=\$__aa__${1}__$2;;
esac"
}
## aset STEM KEY VALUE
## Set KEY to VALUE in the associative array named STEM.
aset () {
eval "__aa__${1}__${2}=\$3
case \$__aa__${1} in
*\" $2 \"*) :;;
*) __aa__${1}=\"\${__aa__${1}}$2 \";;
esac"
}
## aunset STEM KEY
## Remove KEY from the associative array named STEM.
aunset () {
eval "unset __aa__${1}__${2}
case \$__aa__${1} in
*\" $2 \"*) __aa__${1}=\"\${__aa__${1}%%* $2 } \${__aa__${1}#* $2 }\";;
esac"
}
(Avertissement, code non testé. La détection d'erreurs pour les clés et les clés syntaxiquement invalides n'est pas fournie.)