Cómo trabajar con arreglos en scripts de Bash 1

Cómo trabajar con arreglos en scripts de Bash

Índice
  1. Declarando un arreglo
  2. Recorriendo un arreglo
  3. Diferentes tipos de arreglos en Bash
    1. Arreglos indexados
    2. Arreglos asociativos
    3. Arreglos dispersos
  4. Acceder, modificar y eliminar elementos de un arreglo
  5. Algunos trucos avanzados de arreglos
    1. Corte
    2. Copiar y combinar
    3. Ordenar
    4. Eliminar duplicados
    5. Filtrar arreglos

Aprender a usar arreglos en Bash transforma tus scripts, haciéndolos más eficientes y manejables; dominar su sintaxis es clave para gestionar grandes conjuntos de datos de manera efectiva.

Si estás trabajando con una gran cantidad de datos en tus scripts de Bash, los arreglos te facilitarán mucho la vida. Algunas personas se intimidan por la sintaxis. Pero una vez que lo aprendes, hará que tus scripts sean más potentes, con menos variables en las que pensar.

Declarando un arreglo

Los arreglos en Bash te permiten almacenar múltiples piezas de datos en una sola variable, al igual que una lista de Python. Esto los convierte en herramientas poderosas para gestionar conjuntos de valores relacionados, como nombres de archivos, nombres de usuario, opciones de configuración o argumentos de línea de comandos.

A diferencia de muchos otros lenguajes de programación, Bash no requiere que declares explícitamente un tipo de arreglo. Simplemente asignas valores utilizando una sintaxis específica, y Bash entiende que es un arreglo. El método de declaración varía dependiendo del tipo de arreglo (cobierto más adelante).

Para declarar un arreglo indexado, que es el tipo de arreglo más común, simplemente escribe el nombre, un signo igual y paréntesis.

arr=()

Eso es todo. Acabas de declarar un arreglo vacío. Puedes ver sus elementos usando el comando echo, así:

echo $arr

Dado que no hay elementos, no verás nada excepto una línea en blanco. Puedes asignar valores al arreglo en la misma línea. Para hacer eso, escribe elementos separados por espacios dentro de los paréntesis.

fruits=("manzana" "plátano" "cereza")

Cada valor separado por espacios se convierte en un elemento del arreglo. Puedes verificarlo con:

echo "${fruits[@]}"

También puedes declarar un arreglo vacío y agregar elementos más tarde.

fruits=()
fruits+=("manzana")
fruits+=("plátano" "cereza")

Imprimir el arreglo mostrará los elementos recién añadidos.

Este enfoque es útil si necesitas llenar el arreglo dinámicamente. También puedes asignar elementos individuales por índice.

fruits[0]="manzana"
fruits[1]="plátano"
fruits[2]="cereza"

Otra forma de declarar un arreglo es utilizando el declare incorporado para definir explícitamente un arreglo indexado.

declare -a colors=("rojo" "verde" "azul")

Esto deja claro a los demás que 'colors' está destinado a ser un arreglo, lo que puede ser útil en scripts más grandes. Para confirmar si una variable de Bash es un arreglo (y de qué tipo), usa el comando declare -p.

Esto es particularmente útil al depurar scripts.

Recorriendo un arreglo

Una vez que has declarado un arreglo, generalmente querrás hacer algo con sus elementos: imprimirlos, procesarlos o pasarlos a comandos. En Bash, hay varias formas de recorrer arreglos, y entender estos enfoques es clave para escribir scripts flexibles y sin errores.

La forma más común de iterar a través de cada elemento en un arreglo es con un simple bucle for de Bash.

fruits=("manzana" "plátano" "cereza")

for fruit in "${fruits[@]}"; do
echo "Me gusta $fruit"
done

Esto es excelente para recorrer los valores. Pero, ¿qué pasa si también necesitas los índices? Para eso, puedes usar un bucle for estilo C, así:

for ((i=0; i<${#fruits[@]}; i++)); do
echo "Fruta #$i es ${fruits[$i]}"
done

Esto es ideal si necesitas tanto la posición como el valor. Para obtener solo los índices, puedes usar la expansión especial ${!array[@]}, así:

for index in "${!fruits[@]}"; do
echo "Índice $index = ${fruits[$index]}"
done

Esta técnica también es útil cuando el arreglo no es secuencial (por ejemplo, si se eliminaron algunos elementos). Si tu arreglo proviene de la salida de un comando, un bucle while read puede ser más eficiente o limpio.

printf '%s\n' "${lines[@]}" | while read -r file; do
echo "Procesando $file"
done

Este enfoque es excelente al leer datos dinámicamente de comandos o archivos. Otro truco interesante es que puedes recorrer múltiples arreglos juntos. Aquí tienes un ejemplo:

names=("Alicia" "Bob" "Charlie")
ages=(25 30 35)

for ((i=0; i echo "${names[$i]} tiene ${ages[$i]} años"
done

Al recorrer múltiples arreglos juntos, siempre asegúrate de que tengan la misma longitud.

Diferentes tipos de arreglos en Bash

Los arreglos de Bash vienen en algunas variedades, y entender sus diferencias te ayuda a elegir la herramienta adecuada para tu script. Bash admite dos tipos principales de arreglos:

  1. Arreglos indexados: estándar.
  2. Arrays indexados por números.
  3. Arrays asociativos: pares clave-valor indexados por cadenas.

También hay un tipo especial que vale la pena mencionar llamado arreglos dispersos, donde los índices numéricos no son secuenciales. Vamos a repasar cada tipo.

Arreglos indexados

Los arreglos indexados son el tipo más común, perfectos cuando quieres almacenar listas ordenadas como nombres de archivos, ID de usuarios o números. Cada elemento se identifica mediante un índice entero que comienza en 0.

frutas=("manzana" "banana" "cereza")

echo "${frutas[0]}"
echo "${frutas[1]}"

Puedes ver todos los elementos a la vez o verificar el número de elementos:

echo "${frutas[@]}"
echo "${#frutas[@]}"

Los arreglos indexados son útiles cuando tienes una lista con un orden natural, o quieres iterar a través de los resultados de comandos.

Arreglos asociativos

Los arreglos asociativos actúan como diccionarios o mapas hash en muchos otros lenguajes. Te permiten asignar valores a claves de cadena en lugar de índices numéricos.

declare -A capitales=(
[Francia]="París"
[Italia]="Roma"
[Japón]="Tokio"
)
echo "${capitales[Francia]}"

Puedes recorrerlos fácilmente:

for pais in "${!capitales[@]}"; do
echo "$pais → ${capitales[$pais]}"
done

Ten en cuenta que el orden de las claves en los arreglos asociativos es indefinido. Si el orden importa, necesitarás ordenarlos manualmente. Los arreglos asociativos son útiles cuando necesitas mapear relaciones o manejar datos en formato JSON.

Arreglos dispersos

Los arreglos dispersos son una función menos conocida pero interesante. Son arreglos indexados con huecos en su numeración. Puedes asignar elementos a índices arbitrarios. Bash no requiere que sean secuenciales.

numeros=()
numeros[2]=200
numeros[10]=1000
numeros[42]=4200

echo "${!numeros[@]}"

Acceder a índices no establecidos no devolverá nada:

echo "${numeros[5]}"

Aún puedes recorrer los elementos existentes de manera segura. Si tienes un conjunto de datos grande donde no se utiliza cada índice, o trabajas con resultados que naturalmente tienen “huecos”, entonces la característica dispersa puede ser útil.

Acceder, modificar y eliminar elementos de un arreglo

Una vez que has declarado y poblado un arreglo, el siguiente paso es aprender cómo obtener valores, actualizarlos y eliminarlos cuando sea necesario. Trabajar con elementos de arreglos en Bash es sencillo, pero hay algunos comportamientos sutiles que vale la pena recordar.

Puedes acceder a un elemento por su índice (para arreglos indexados) o clave (para arreglos asociativos). Para arreglos indexados:

frutas=("manzana" "banana" "cereza")

echo "${frutas[0]}"
echo "${frutas[2]}"

Para arreglos asociativos:

declare -A capitales=(
[Francia]="París"
[Italia]="Roma"
[Japón]="Tokio"
)

echo "${capitales[Japón]}"

En ambos casos, si el índice o la clave no tienen un valor, recibirás una cadena vacía como salida. Si deseas acceder a todos los elementos o índices a la vez, hay algunas sintaxis especiales. Aquí tienes una guía que puedes seguir.

Síntaxis de expansión

Descripción

${array[@]}

Todos los valores

${!array[@]}

Todos los índices o claves

${#array[@]}

Número de elementos

${array[*]}

Todos los valores (fusionados en una cadena)

Siempre cita tus expansiones: "${array[@]}". Las expansiones no citadas pueden romperse cuando los elementos contienen espacios o comodines.

Para modificar un elemento de un arreglo, simplemente reasígnalo:

frutas[1]="mora"
echo "${frutas[1]}"
frutas[1]="arándano"
echo "${frutas[1]}"

También puedes agregar nuevos elementos:

frutas+=("fruta-dragón")

Para arreglos asociativos, reasignas valores a las claves.

capitales["Francia"]="París"
echo "${capitales[Francia]}"
capitales["Francia"]="Marsella"
echo "${capitales[Francia]}"

Reasignar un valor sobrescribe el anterior, así que ten cuidado al realizar esta acción.

Para eliminar un elemento, puedes usar el comando unset. Puede eliminar elementos específicos o todo el arreglo.

unset 'frutas[1]'
echo.
"${fruits[@]}"

Para eliminar múltiples elementos:

unset 'fruits[0]' 'fruits[2]'

Para eliminar todo el arreglo, simplemente pasa el nombre del arreglo:

unset fruits

Lo mismo se aplica para arreglos asociativos. Usa el comando unset y la clave (en lugar del índice) para eliminar ese elemento.

unset 'capitals[Francia]'

Si deseas modificar o eliminar múltiples valores, usar un bucle for para iterar a través del arreglo es una buena idea.

Algunos trucos avanzados de arreglos

Hasta ahora, sabes cómo declarar, recorrer y manipular arreglos. Sin embargo, Bash puede hacer mucho más con ellos. Veamos algunas técnicas avanzadas de arreglos que pueden hacer que tus scripts sean más inteligentes y fáciles de mantener.

Corte

Puedes extraer subconjuntos de arreglos utilizando la sintaxis de corte.

${array[@]:inicio:largo}

Aquí, inicio se refiere al primer elemento del corte, mientras que largo se refiere a cuántos elementos deseas mantener en el subconjunto. Ten en cuenta que los arreglos en Bash tienen índice basado en 0. Ejemplo:

numbers=(10 20 30 40 50)
echo "${numbers[@]:1:3}"

Tenemos los tres elementos del medio ya que comenzamos el corte desde el índice uno. Esto es útil cuando deseas procesar una porción de los resultados de un comando.

Copiar y combinar

Copiar un arreglo simplemente requiere que asignes los elementos del arreglo a otro nuevo arreglo.

copy=("${fruits[@]}")

Bash copia arreglos por valor, no por referencia. Por lo tanto, modificar 'copy' no afectará el original.

Para fusionar dos o más arreglos en uno, pasas sus elementos a un nuevo arreglo utilizando la sintaxis de expansión.

numbers=(1 2 3)
more_numbers=(4 5 6)
combined=("${numbers[@]}" "${more_numbers[@]}")

echo "${combined[@]}"

Ordenar

Ordenar un arreglo significa reorganizarlo en un orden específico. Esto podría ser numérico o alfabético (dependiendo del tipo de elemento), ascendente o descendente. Bash no tiene una función de ordenamiento incorporada, pero es fácil lograrlo con la sustitución de comandos y el comando sort.

fruits=("banana" "manzana" "cereza" "dátil")

IFS=$'\n' sorted=($(sort unset IFS

echo "${sorted[@]}"

Aquí, el comando sort ordena los elementos alfabéticamente. IFS=$'\n' asegura que los elementos que contienen espacios no se dividan incorrectamente. Almacenamos la salida ordenada en un nuevo arreglo.

De manera similar, también podemos hacer un ordenamiento inverso.

IFS=$'\n' sorted=($(sort -r unset IFS

En el caso de datos numéricos, puedes usar sort -n.

numbers=(42 5 19 100 3)
IFS=$'\n' sorted_nums=($(sort -n unset IFS
echo "${sorted_nums[@]}"

Eliminar duplicados

Un problema clásico. Elimina cualquier elemento duplicado en el arreglo para que todos los elementos restantes sean únicos. Podemos volver a apoyarnos en el comando sort.

numbers=(1 2 2 3 4 3 5)

unique=($(printf "%s\n" "${numbers[@]}" | sort -u))
echo "${unique[@]}"

Este enfoque funciona imprimiendo todos los elementos, ordenándolos y eliminando duplicados con -u. Sin embargo, este método depende del orden. Ordena tu arreglo en el proceso. Si necesitas mantener el orden original, tendrás que recorrer y rastrear los elementos vistos manualmente.

Filtrar arreglos

El último truco que me gustaría cubrir es filtrar elementos de un arreglo. Haremos esto utilizando el emparejamiento de patrones y la expansión de parámetros.

files=("data.txt" "imagen.png" "notas.txt" "script.sh")

txt_files=()
for f in "${files[@]}"; do
[[ $f == *.txt ]] && txt_files+=("$f")
done

echo "${txt_files[@]}"

Este truco es simple pero poderoso al manejar listas de archivos mixtos o conjuntos de datos.

Con esto, deberías tener una buena comprensión de cómo usar arreglos en Bash para manipular tus datos. Esto te ayudará a escribir mejores scripts. Puedes comenzar revisando algunos scripts de ejemplo en Bash.

Si deseas encontrar artículos similares a Cómo trabajar con arreglos en scripts de Bash, te sugerimos revisar la categoría Tutoriales.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir