Conchas con matrices asociativas
Algunos shells modernos proporcionan matrices asociativas: ksh93, bash ≥4, zsh. En ksh93 y bash, si a
es una matriz asociativa, entonces "${!a[@]}"
es la matriz de sus claves:
for k in "${!a[@]}"; do
echo "$k -> ${a[$k]}"
done
En zsh, esa sintaxis solo funciona en el modo de emulación ksh. De lo contrario, debe usar la sintaxis nativa de zsh:
for k in "${(@k)a}"; do
echo "$k -> $a[$k]"
done
${(k)a}
También funciona si a
no tiene una clave vacía.
En zsh, también puede hacer un bucle en k
eys y v
alues al mismo tiempo:
for k v ("${(@kv)a}") echo "$k -> $v"
Conchas sin matrices asociativas
Emular matrices asociativas en shells que no las tienen es mucho más trabajo. Si necesita matrices asociativas, probablemente sea hora de traer una herramienta más grande, como ksh93 o Perl.
Si necesita matrices asociativas en un simple shell POSIX, aquí hay una manera de simularlas, cuando las claves están restringidas para contener solo los caracteres 0-9A-Z_a-z
(dígitos ASCII, letras y guiones bajos). Bajo este supuesto, las claves pueden usarse como parte de nombres de variables. Las funciones a continuación actúan sobre una matriz identificada por un prefijo de denominación, la "raíz", que no debe contener dos guiones bajos 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"
}
(Advertencia, código no probado. No se proporciona detección de errores para claves y tallos sintácticamente inválidos).