Ar

Arrays en Bash

{one: "1 ejercicio", many: "%{count} ejercicios", other: "%{count} ejercicios"}

Acerca de Arrays

Bash proporciona dos tipos de parámetros: valores «escalares» y arrays. Un valor escalar puede ser un string o un número; representa una única «cosa».

La mayoría de las veces, los valores escalares bastan para contener tus datos. Pero a veces necesitas almacenar varios valores escalares. En ese caso usarás un array.

Hay dos tipos de arrays:

  • Los arrays indexados numéricamente asocian una clave entera a un valor de tipo string. (En otros lenguajes, esto podría llamarse «list» o «sequence».)
  • Los arrays asociativos asocian una clave de tipo string a un valor de tipo string. (En otros lenguajes, esto podría llamarse «map» o «dictionary».)

Las primeras secciones de este documento tratan los arrays indexados numéricamente (en adelante, simplemente «arrays»). Los detalles sobre los arrays asociativos aparecen al final.

Caution

Los arrays de Bash solo pueden almacenar valores escalares. No es posible crear un array bidimensional (un array de arrays).

Declarar e inicializar una variable de tipo array

Puedes inicializar un array asignando una lista de elementos entre paréntesis (posiblemente vacía) a una variable.

myarray=("one" "two" "three")

Como ocurre con toda asignación de variable, no debe haber espacios alrededor del signo igual.

Fíjate en que no hay comas que separen los elementos; es una lista de strings separados por espacios en blanco.

De hecho, la cantidad de espacios en blanco dentro de los paréntesis es totalmente arbitraria. Se permiten saltos de línea; usa tantos como quieras para mejorar la legibilidad.

myarray=(
    "first element"
    "second element"
    "this is the last element"
)

Asignar una lista de strings a una variable de tipo array de esta forma almacena el primer string en el índice cero, el siguiente en el índice uno, el siguiente en el índice dos, y así sucesivamente.

Es posible inicializar un «array disperso» especificando los índices que necesitas.

raindrops=([3]="Pling" [5]="Plang" [7]="Plong")
Note

Para reiterarlo: los índices de los arrays empiezan en cero. Este fragmento muestra «true»:

myarray=("one" "two" "three")
[[ "${myarray[0]}" == "one" ]] && echo true || echo false

Puedes usar el comando declare (o local dentro de una función) para indicar que una variable contendrá un array.

declare -a myarray

Es más idiomático simplemente asignar una lista entre paréntesis (quizá vacía) para inicializar la variable.

Acceder a los elementos de un array

Como viste en la nota anterior, la sintaxis para acceder a un elemento de un array es ${myarray[$index]}. El índice se indica entre corchetes. Las llaves son obligatorias.

Note

En los arrays indexados numéricamente, el índice es una expresión aritmética. El manual de Bash dice:

Dentro de una expresión aritmética, las variables del shell también pueden referenciarse por su nombre sin usar la sintaxis de expansión de parámetros.

Esto significa que el $ no es necesario para la expansión de variables «simple». Puedes acceder a los elementos así, lo que resulta algo más fácil de leer:

i=5
echo "${myarray[i]}"
# ..............^

Si el índice indicado no existe en el array, el resultado de la expansión es un string vacío.

Asignar valores a un array

Para asignar un valor a una entrada concreta del array, usa esta sintaxis:

myarray[10]="hello"

Para añadir elementos a un array, usa el operador de asignación por concatenación += y utiliza paréntesis:

myarray+=("new element 1" "new element 2")

Recorrer un array

Normalmente necesitarás recorrer los valores de un array. Usa un bucle for (el que viste en el concepto Bucles):

myarray=("one" "two" "three")
for value in "${myarray[@]}"; do
    echo "$value"
done

Fíjate en la sintaxis especial para expandir el array: "${myarray[@]}" Esta forma de expansión de parámetros sustituye los valores del array como palabras separadas. Es más o menos equivalente a:

for value in "${myarray[0]}" "${myarray[1]}" ... "${myarray[n]}"

La forma "${myarray[@]}" funciona con arrays dispersos y se expande solo a los valores definidos.

Esta expansión especial, en la que el índice es un signo arroba (@), solo es especial dentro de comillas dobles.

Otras expansiones especiales de parámetros

Aquí tienes un par de fragmentos más de sintaxis especial que necesitamos para recorrer un array. Se describen en el manual, en Expansión de parámetros del shell.

Para obtener la longitud de un array, usa ${#myarray[@]}, con un # delante del nombre. La «longitud» de un array es el número de elementos que contiene.

Para extraer la lista de índices de un array, usa "${!myarray[@]}", con un ! delante del nombre y la expansión entre comillas dobles. En los arrays indexados numéricamente, los índices se expanden en orden numérico.

Recorrer los índices de un array

A veces necesitas el índice además del valor. Hay un par de formas de hacerlo.

  1. Cuando sabes que los índices forman una secuencia ininterrumpida, puedes usar un bucle for aritmético.

    for ((i = 0; i < ${#myarray[@]}; i++)); do
        echo "$i -> ${myarray[i]}"
    done
    

    Fíjate en la sintaxis ${#myarray[@]}, con el carácter # delante del nombre del array. Como los arrays usan índices que empiezan en cero, el último índice es una unidad menor que la longitud del array.

  2. Cuando el array es disperso, puedes usar esta forma:

    for index in "${!raindrops[@]}"; do
        echo "$index -> ${raindrops[index]}"
    done
    

    Fíjate en la sintaxis ${!myarray[@]}, con el carácter ! delante del nombre del array.

Inspeccionar un array

Si quieres ver el contenido de un array, usa el comando declare con la opción -p:

a=("the 'first' element"
   second
   third
   'the "last" element')
declare -p a

Esto muestra el contenido con el entrecomillado canónico del shell.

declare -a a=([0]="the 'first' element" [1]="second" [2]="third" [3]="the \"last\" element")

Arrays asociativos

Para reiterarlo, los arrays asociativos usan strings como índices, no números. Todo lo escrito arriba se aplica a los arrays asociativos, pero con pequeñas diferencias. En general, usamos el término «clave» en lugar de «índice»: los arrays asociativos asocian claves a valores.

Declarar un array asociativo

A diferencia de los arrays, los arrays asociativos deben declararse. Usa la opción -A de declare (o de local dentro de una función):

declare -A mymap

myfunc() {
    local -A my_local_map
    # ...
}

Inicializar un array asociativo

Los pares clave-valor se indican dentro de la lista entre paréntesis:

mymap=([first]=foo [second]=bar [third]=baz)
declare -p mymap

Esto muestra:

declare -A mymap=([second]="bar" [first]="foo" [third]="baz")
Note

Ten en cuenta que los arrays asociativos no tienen orden.

La declaración y la inicialización pueden hacerse en una sola línea.

declare -A mymap=([first]=foo [second]=bar [third]=baz)

En versiones recientes de Bash, la inicialización puede usar una lista (key value key value ...).

declare -A mymap=(first foo second bar third baz)

Acceder a los valores

Para acceder a los elementos se usa la misma sintaxis que antes: ${mymap[$key]}.

Las claves de los arrays asociativos no se evalúan en un contexto aritmético. Se requiere la sintaxis habitual de expansión de parámetros.

Asignar valores a un array asociativo

La asignación usa la misma sintaxis que antes:

mymap[$key]="$value"

Recorrer

Puedes usar un bucle for value in "${mymap[@]}" para recorrerlo. Sin embargo, normalmente también quieres la clave junto con el valor.

Usa la sintaxis "${!mymap[@]}" que vimos antes.

for key in "${!mymap[@]}"; do
    echo "$key -> ${mymap[$key]}"
done

Esto muestra

second -> bar
first -> foo
third -> baz

Para recalcarlo: las claves no tienen ningún orden.

Editar en GitHub El enlace se abre en una nueva ventana o pestaña