GNU/Linux >> Tutoriales Linux >  >> Linux

¿Matrices asociativas en scripts de Shell?

Vi un truco para implementar matrices asociativas en un script de shell. Por ejemplo print array["apples"] podría escribirse como echo $array$key donde clave=manzanas.

Sin embargo, no se mencionó cómo generar las claves para iterar sobre la matriz.
La única forma que se me ocurrió fue almacenar las claves en una variable delimitada por espacios para poder usar un ciclo for para iterar sobre la matriz.

Entonces, ¿hay alguna otra forma de almacenar las claves para su uso posterior?

Respuesta aceptada:

Conchas con arreglos asociativos

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 llave vacía.

En zsh, también puede hacer un bucle en ambos k teclas y v valores al mismo tiempo:

for k v ("${(@kv)a}") echo "$k -> $v"

Conchas sin arreglos asociativos

Emular arreglos asociativos en shells que no los tienen es mucho más trabajo. Si necesita matrices asociativas, probablemente sea el momento de incorporar una herramienta más grande, como ksh93 o Perl.

Si necesita matrices asociativas en un simple shell POSIX, aquí hay una forma de simularlas, cuando las claves están restringidas para contener solo los caracteres 0-9A-Z_a-z (Dígitos ASCII, letras y guión bajo). Bajo esta suposición, las claves se pueden usar como parte de los nombres de variables. Las siguientes funciones actúan sobre una matriz identificada por un prefijo de nombre, 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 raíces y claves sintácticamente inválidas).

Relacionado:Linux – medios lentos – ajuste de caché de disco?
Linux
  1. ¿Permitir Setuid en scripts de Shell?

  2. Matrices en Unix Bourne Shell?

  3. ¿Cómo eliminar los privilegios de raíz en los scripts de Shell?

  4. ¿Ejecutar scripts de Shell a través de un sitio web?

  5. ¿Ocultar la contraseña en los scripts de Shell?

Cómo crear scripts de shell

Matrices en scripts de Shell

¿Cómo usar if-else en Shell Scripts?

Comprender el bucle for en los scripts de Shell

El bucle while en los scripts de Shell

Ejecutar scripts desde otro directorio