Conchas com matrizes associativas
Alguns shells modernos fornecem matrizes associativas: ksh93, bash ≥4, zsh. No ksh93 e no bash, se a
for uma matriz associativa, "${!a[@]}"
é a matriz de suas chaves:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
No zsh, essa sintaxe funciona apenas no modo de emulação ksh. Caso contrário, você precisará 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 fazer o loop em k
eys e v
alues ao mesmo tempo:
for k v ("${(@kv)a}") echo "$k -> $v"
Cascas sem matrizes associativas
Emular matrizes associativas em conchas que não as possuem é muito mais trabalhoso. Se você precisar de matrizes associativas, provavelmente é hora de trazer uma ferramenta maior, como ksh93 ou Perl.
Se você precisar de matrizes associativas em um mero 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 sublinhado). Sob essa suposição, as chaves podem ser usadas como parte dos nomes de variáveis. As funções abaixo atuam em uma matriz identificada por um prefixo de nomenclatura, o "tronco", 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}=\$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"
}
(Aviso, código não testado. A detecção de erros para hastes e chaves sintaticamente inválidas não é fornecida.)