Shells com matrizes associativas
Algumas shells modernas fornecem matrizes associativas: ksh93, bash ≥4, zsh. Em ksh93 e bash, se a
for uma matriz associativa, então "${!a[@]}"
é a matriz de suas chaves:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
No zsh, essa sintaxe só funciona no modo de emulação ksh. Caso contrário, você terá que usar a sintaxe nativa do zsh:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
${(k)a}
também funciona se a
não tiver uma chave vazia.
No zsh, você também pode executar o loop nos dois k
eys e v
alues ao mesmo tempo:
for k v ("${(@kv)a}") echo "$k -> $v"
Conchas sem matrizes associativas
Emular matrizes associativas em shells que não as têm é muito mais trabalhoso. Se você precisa de matrizes associativas, provavelmente é hora de trazer uma ferramenta maior, como ksh93 ou Perl.
Se você precisa de matrizes associativas em um simples shell POSIX, aqui está uma maneira de simulá-las, quando as chaves são restritas para conter apenas os caracteres 0-9A-Z_a-z
(dígitos ASCII, letras e sublinhados). Sob esta suposição, as chaves podem ser usadas como parte dos nomes das variáveis. As funções abaixo atuam em uma matriz identificada por um prefixo de nomenclatura, o "radical", que não deve conter dois sublinhados consecutivos.
## 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}=\
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"
}
(Aviso, código não testado. Detecção de erro para hastes e chaves sintaticamente inválidas não é fornecida.)