Cómo imprimir elementos de un array de Bash línea por línea

ShellBeginner
Practicar Ahora

Introducción

En este tutorial, exploraremos los arrays (arreglos) de Bash y aprenderemos cómo imprimir cada elemento en una nueva línea, lo cual es un requisito común en la programación de scripts de shell. Los arrays de Bash te permiten almacenar múltiples valores en una sola variable, lo que los hace esenciales para organizar datos en tus scripts.

Al final de este laboratorio (lab), entenderás cómo crear arrays, manipular sus elementos y utilizar diferentes técnicas para imprimir el contenido de los arrays, uno por línea. Estas habilidades te ayudarán a escribir scripts de shell más eficientes y legibles para tareas como procesar listas de archivos, manejar salidas de comandos y automatizar tareas de administración de sistemas.

Creación y comprensión de los arrays (arreglos) de Bash

Los arrays de Bash te permiten almacenar múltiples valores en una sola variable. Aprendamos cómo crearlos y trabajar con ellos.

Creando tu primer array

Abre una terminal en el WebIDE. Por defecto, deberías estar en el directorio /home/labex/project. Comencemos creando un simple script de Bash:

  1. En el WebIDE, crea un nuevo archivo llamado array_demo.sh haciendo clic en el icono "Nuevo archivo" en el panel del explorador o utilizando la opción del menú "Archivo > Nuevo archivo".

  2. Añade el siguiente contenido al archivo:

#!/bin/bash

## Create an array of fruits
fruits=("apple" "banana" "orange" "grape" "kiwi")

## Print the entire array
echo "All fruits: ${fruits[@]}"

## Print the first element (index 0)
echo "First fruit: ${fruits[0]}"

## Print the third element (index 2)
echo "Third fruit: ${fruits[2]}"

## Print the number of elements in the array
echo "Number of fruits: ${#fruits[@]}"
  1. Guarda el archivo presionando Ctrl+S o utilizando la opción del menú "Archivo > Guardar".

  2. Ahora, haz el script ejecutable ejecutando este comando en la terminal:

chmod +x /home/labex/project/array_demo.sh
  1. Ejecuta el script:
./array_demo.sh

Deberías ver una salida similar a esta:

All fruits: apple banana orange grape kiwi
First fruit: apple
Third fruit: orange
Number of fruits: 5

Comprendiendo la sintaxis de los arrays

Desglosemos la sintaxis de los arrays:

  • Crear un array: fruits=("apple" "banana" "orange" "grape" "kiwi")
    Esto crea un array llamado fruits con cinco elementos.

  • Acceder a todos los elementos: ${fruits[@]}
    El símbolo @ se refiere a todos los elementos del array.

  • Acceder a un elemento específico: ${fruits[0]}, ${fruits[2]}
    Los arrays en Bash tienen índices que comienzan en cero, lo que significa que el primer elemento está en el índice 0.

  • Obtener la longitud del array: ${#fruits[@]}
    El símbolo # antes de la referencia al array devuelve el número de elementos.

Diferentes formas de crear arrays

Creemos un nuevo script para demostrar diferentes formas de crear arrays:

  1. Crea un nuevo archivo llamado array_creation.sh:
#!/bin/bash

## Method 1: Direct declaration
colors=("red" "green" "blue" "yellow")
echo "Colors array: ${colors[@]}"

## Method 2: Individual element assignment
shapes=()
shapes[0]="circle"
shapes[1]="square"
shapes[2]="triangle"
echo "Shapes array: ${shapes[@]}"

## Method 3: Create array from command output
files=($(ls /home/labex/project))
echo "Files in current directory: ${files[@]}"

## Method 4: Create array from a string
data="one two three four"
numbers=($data)
echo "Numbers array: ${numbers[@]}"
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/array_creation.sh
  1. Ejecuta el script:
./array_creation.sh

Deberías ver una salida que muestra todos los diferentes arrays que has creado. La salida exacta del array de archivos dependerá de qué archivos existan en tu directorio.

Estos ejemplos demuestran la flexibilidad de los arrays de Bash y cómo puedes crearlos de diferentes maneras según tus necesidades.

Manipulación de elementos de arrays (arreglos)

Ahora que sabemos cómo crear arrays, aprendamos cómo manipularlos agregando, eliminando y modificando elementos.

Modificación de elementos de arrays

Creemos un nuevo script para demostrar la manipulación de arrays:

  1. En el WebIDE, crea un nuevo archivo llamado array_manipulation.sh:
#!/bin/bash

## Create an initial array
fruits=("apple" "banana" "orange")
echo "Initial array: ${fruits[@]}"

## Add an element to the end of the array
fruits+=("grape")
echo "After adding grape: ${fruits[@]}"

## Add multiple elements
fruits+=("kiwi" "mango")
echo "After adding kiwi and mango: ${fruits[@]}"

## Change an element
fruits[1]="blueberry"
echo "After changing banana to blueberry: ${fruits[@]}"

## Remove an element (this leaves an empty slot)
unset fruits[2]
echo "After removing the third element: ${fruits[@]}"

## Print array indices
echo "Array indices: ${!fruits[@]}"

## Recreate array to remove empty slots
new_fruits=()
for fruit in "${fruits[@]}"; do
  if [[ -n "$fruit" ]]; then
    new_fruits+=("$fruit")
  fi
done

fruits=("${new_fruits[@]}")
echo "After removing empty slots: ${fruits[@]}"
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/array_manipulation.sh
  1. Ejecuta el script:
./array_manipulation.sh

La salida debe mostrar cómo cambia el array con cada operación:

Initial array: apple banana orange
After adding grape: apple banana orange grape
After adding kiwi and mango: apple banana orange grape kiwi mango
After changing banana to blueberry: apple blueberry orange grape kiwi mango
After removing the third element: apple blueberry  grape kiwi mango
Array indices: 0 1 3 4 5
After removing empty slots: apple blueberry grape kiwi mango

División (slicing) de arrays

Exploremos cómo extraer porciones de un array:

  1. Crea un nuevo archivo llamado array_slicing.sh:
#!/bin/bash

## Create a sample array
colors=("red" "orange" "yellow" "green" "blue" "indigo" "violet")
echo "Full array: ${colors[@]}"

## Extract a sub-array (starting index and length)
## Syntax: ${array[@]:start:length}
sub_array1=("${colors[@]:1:3}")
echo "Sub-array (indices 1-3): ${sub_array1[@]}"

## Extract from an index to the end
sub_array2=("${colors[@]:4}")
echo "Sub-array (from index 4 to end): ${sub_array2[@]}"

## Extract the last two elements
sub_array3=("${colors[@]: -2}") ## Note the space before -2
echo "Last two elements: ${sub_array3[@]}"
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/array_slicing.sh
  1. Ejecuta el script:
./array_slicing.sh

La salida demostrará diferentes formas de dividir arrays:

Full array: red orange yellow green blue indigo violet
Sub-array (indices 1-3): orange yellow green
Sub-array (from index 4 to end): blue indigo violet
Last two elements: indigo violet

Búsqueda de elementos en arrays

Creemos un script para demostrar cómo buscar elementos en un array:

  1. Crea un nuevo archivo llamado array_searching.sh:
#!/bin/bash

## Create a sample array
fruits=("apple" "banana" "orange" "grape" "kiwi")
echo "Our fruits: ${fruits[@]}"

## Function to search for an element in an array
search_array() {
  local needle="$1"
  shift
  local haystack=("$@")

  for i in "${!haystack[@]}"; do
    if [[ "${haystack[$i]}" == "$needle" ]]; then
      echo "Found '$needle' at index $i"
      return 0
    fi
  done

  echo "'$needle' not found in the array"
  return 1
}

## Search for some fruits
search_array "orange" "${fruits[@]}"
search_array "banana" "${fruits[@]}"
search_array "watermelon" "${fruits[@]}"
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/array_searching.sh
  1. Ejecuta el script:
./array_searching.sh

La salida mostrará los resultados de buscar diferentes elementos:

Our fruits: apple banana orange grape kiwi
Found 'orange' at index 2
Found 'banana' at index 1
'watermelon' not found in the array

Estos ejemplos demuestran las operaciones comunes que se pueden realizar en arrays de Bash, que son habilidades esenciales para trabajar con colecciones de datos en tus scripts.

Impresión de elementos de un array línea por línea

En este paso, nos centraremos en el tema principal de nuestro laboratorio: imprimir los elementos de un array línea por línea. Exploraremos diferentes métodos para lograr esto en Bash.

Método 1: Utilizando un bucle for

La forma más directa de imprimir los elementos de un array línea por línea es utilizando un bucle for:

  1. Crea un nuevo archivo llamado print_array_loop.sh:
#!/bin/bash

## Create a sample array
planets=("Mercury" "Venus" "Earth" "Mars" "Jupiter" "Saturn" "Uranus" "Neptune")

echo "Printing planets using a for loop:"
for planet in "${planets[@]}"; do
  echo "$planet"
done
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/print_array_loop.sh
  1. Ejecuta el script:
./print_array_loop.sh

La salida mostrará cada planeta en una línea separada:

Printing planets using a for loop:
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune

Método 2: Utilizando el comando printf

El comando printf suele ser más eficiente que utilizar un bucle con echo:

  1. Crea un nuevo archivo llamado print_array_printf.sh:
#!/bin/bash

## Create a sample array
planets=("Mercury" "Venus" "Earth" "Mars" "Jupiter" "Saturn" "Uranus" "Neptune")

echo "Printing planets using printf:"
printf "%s\n" "${planets[@]}"
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/print_array_printf.sh
  1. Ejecuta el script:
./print_array_printf.sh

La salida será la misma que en el método anterior:

Printing planets using printf:
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune

Método 3: Utilizando la variable IFS

La variable Internal Field Separator (IFS, Separador de Campos Interno) se puede utilizar para controlar cómo se imprimen los elementos de un array:

  1. Crea un nuevo archivo llamado print_array_ifs.sh:
#!/bin/bash

## Create a sample array
planets=("Mercury" "Venus" "Earth" "Mars" "Jupiter" "Saturn" "Uranus" "Neptune")

echo "Printing planets using IFS:"
## Temporarily change IFS to newline
old_IFS="$IFS"
IFS=$'\n'
echo "${planets[*]}" ## Note: using * instead of @ with IFS
IFS="$old_IFS"       ## Restore original IFS
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/print_array_ifs.sh
  1. Ejecuta el script:
./print_array_ifs.sh

La salida mostrará una vez más cada planeta en una línea separada:

Printing planets using IFS:
Mercury
Venus
Earth
Mars
Jupiter
Saturn
Uranus
Neptune

Método 4: Combinación de múltiples técnicas

Combinemos estas técnicas en un ejemplo más completo:

  1. Crea un nuevo archivo llamado print_array_combined.sh:
#!/bin/bash

## Create a sample array
planets=("Mercury" "Venus" "Earth" "Mars" "Jupiter" "Saturn" "Uranus" "Neptune")

echo "Using a for loop with index:"
for i in "${!planets[@]}"; do
  echo "Planet $i: ${planets[$i]}"
done

echo -e "\nUsing printf with formatting:"
printf "Planet: %s - %d letters\n" "${planets[@]}" "${#planets[@]}"

echo -e "\nSorted planets:"
printf "%s\n" "${planets[@]}" | sort
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/print_array_combined.sh
  1. Ejecuta el script:
./print_array_combined.sh

La salida mostrará diferentes formas de formatear e imprimir los elementos de un array:

Using a for loop with index:
Planet 0: Mercury
Planet 1: Venus
Planet 2: Earth
Planet 3: Mars
Planet 4: Jupiter
Planet 5: Saturn
Planet 6: Uranus
Planet 7: Neptune

Using printf with formatting:
Planet: Mercury - 8 letters
Planet: Venus - 5 letters
Planet: Earth - 5 letters
Planet: Mars - 4 letters
Planet: Jupiter - 7 letters
Planet: Saturn - 6 letters
Planet: Uranus - 7 letters
Planet: Neptune - 7 letters

Sorted planets:
Earth
Jupiter
Mars
Mercury
Neptune
Saturn
Uranus
Venus

Cada uno de estos métodos tiene sus ventajas:

  • El bucle for es más legible para los principiantes.
  • El método de printf es más eficiente para arrays grandes.
  • El método de IFS es compacto pero puede ser menos intuitivo.
  • Las técnicas combinadas pueden proporcionar opciones de formato más ricas.

Elige el método que mejor se adapte a tu caso de uso específico y a tu estilo de codificación.

Aplicaciones prácticas con arrays

En este último paso, exploraremos aplicaciones del mundo real de los arrays de Bash y aplicaremos las técnicas que hemos aprendido para imprimir elementos línea por línea.

Procesamiento de una lista de archivos

Creemos un script que procese archivos en un directorio:

  1. Primero, creemos algunos archivos de muestra con los que trabajar:
mkdir -p /home/labex/project/sample_files
touch /home/labex/project/sample_files/file1.txt
touch /home/labex/project/sample_files/file2.txt
touch /home/labex/project/sample_files/file3.txt
touch /home/labex/project/sample_files/image1.jpg
touch /home/labex/project/sample_files/image2.jpg
  1. Crea un nuevo archivo llamado process_files.sh:
#!/bin/bash

## Get a list of files in the directory
file_path="/home/labex/project/sample_files"
files=($(ls "$file_path"))

echo "All files in directory:"
printf "%s\n" "${files[@]}"

echo -e "\nProcessing text files only:"
text_files=()

## Filter for text files
for file in "${files[@]}"; do
  if [[ "$file" == *.txt ]]; then
    text_files+=("$file")
  fi
done

## Process each text file
if [ ${#text_files[@]} -eq 0 ]; then
  echo "No text files found."
else
  echo "Found ${#text_files[@]} text files:"
  for file in "${text_files[@]}"; do
    echo "Processing $file..."
    ## Here you would typically do something with each file
    echo "  - Adding content to $file"
    echo "This is sample content" > "$file_path/$file"
  done
fi

## Verify the content
echo -e "\nContent of text files:"
for file in "${text_files[@]}"; do
  echo "--- $file ---"
  cat "$file_path/$file"
  echo "------------"
done
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/process_files.sh
  1. Ejecuta el script:
./process_files.sh

La salida mostrará cómo procesar y filtrar archivos utilizando arrays:

All files in directory:
file1.txt
file2.txt
file3.txt
image1.jpg
image2.jpg

Processing text files only:
Found 3 text files:
Processing file1.txt...
  - Adding content to file1.txt
Processing file2.txt...
  - Adding content to file2.txt
Processing file3.txt...
  - Adding content to file3.txt

Content of text files:
--- file1.txt ---
This is sample content
------------
--- file2.txt ---
This is sample content
------------
--- file3.txt ---
This is sample content
------------

Creación de un sistema de menú simple

Los arrays pueden ser útiles para crear sistemas de menú en scripts:

  1. Crea un nuevo archivo llamado menu_system.sh:
#!/bin/bash

## Define menu options
options=("List Files" "Check Disk Space" "Display Date" "Display Users" "Exit")

while true; do
  echo -e "\nMenu Options:"
  ## Print menu with numbers
  for i in "${!options[@]}"; do
    echo "  $((i + 1)). ${options[$i]}"
  done

  ## Get user choice
  read -p "Enter your choice (1-${#options[@]}): " choice

  ## Convert to zero-based index
  ((choice--))

  ## Process choice
  case $choice in
    0) ## List Files
      echo -e "\nFiles in current directory:"
      ls -la /home/labex/project
      ;;
    1) ## Check Disk Space
      echo -e "\nDisk space usage:"
      df -h
      ;;
    2) ## Display Date
      echo -e "\nCurrent date and time:"
      date
      ;;
    3) ## Display Users
      echo -e "\nCurrently logged in users:"
      who
      ;;
    4) ## Exit
      echo "Exiting menu system. Goodbye!"
      exit 0
      ;;
    *)
      echo "Invalid choice. Please try again."
      ;;
  esac

  ## Pause before showing menu again
  read -p "Press Enter to continue..."
done
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/menu_system.sh
  1. Ejecuta el script:
./menu_system.sh
  1. Verás un sistema de menú. Prueba a seleccionar diferentes opciones para ver los resultados. Cuando hayas terminado, selecciona la opción 5 para salir.

Procesamiento de la salida de comandos

Los arrays son excelentes para procesar la salida de comandos:

  1. Crea un nuevo archivo llamado process_command_output.sh:
#!/bin/bash

## Get a list of running processes
echo "Getting list of processes..."
processes=($(ps -e | awk '{print $4}' | tail -n +2))

echo "Found ${#processes[@]} processes"
echo -e "\nTop 10 processes:"
printf "%s\n" "${processes[@]:0:10}"

## Count unique processes
echo -e "\nCounting unique process names..."
declare -A process_count

for process in "${processes[@]}"; do
  ((process_count["$process"]++))
done

echo -e "\nProcess Count Summary:"
for process in "${!process_count[@]}"; do
  echo "$process: ${process_count["$process"]}"
done | sort -rn -k2 | head -10
  1. Guarda el archivo y hazlo ejecutable:
chmod +x /home/labex/project/process_command_output.sh
  1. Ejecuta el script:
./process_command_output.sh

La salida mostrará cómo procesar la salida de comandos utilizando arrays. La salida exacta variará dependiendo de los procesos que se estén ejecutando en tu sistema.

Estos ejemplos demuestran cómo se pueden utilizar los arrays de Bash en escenarios del mundo real para resolver problemas prácticos. La capacidad de procesar listas de elementos e imprimirlos en un formato legible es una habilidad fundamental para la programación de scripts de shell.

Resumen

En este laboratorio, has aprendido habilidades esenciales para trabajar con arrays de Bash:

  1. Creación y comprensión de arrays

    • Declaración de arrays con diferentes métodos
    • Acceso a elementos y propiedades de los arrays
  2. Manipulación de elementos de arrays

    • Adición, eliminación y modificación de elementos
    • División de arrays y búsqueda de elementos
  3. Impresión de elementos de arrays línea por línea

    • Uso de bucles for para iterar a través de arrays
    • Uso del comando printf para una impresión eficiente
    • Aprovechamiento de la variable IFS (Internal Field Separator) para un formato personalizado
    • Combinación de técnicas para un formato de salida avanzado
  4. Aplicaciones prácticas

    • Procesamiento de listas de archivos
    • Creación de sistemas de menú
    • Procesamiento de la salida de comandos

Estas habilidades proporcionan una base sólida para el uso de arrays en tus scripts de Bash. Ahora puedes almacenar, manipular y mostrar colecciones de datos de manera eficiente, lo que hace que tus scripts sean más robustos y versátiles.

Recuerda que la clave para dominar los arrays de Bash es la práctica. Intenta incorporar estas técnicas en tus propios scripts y explora cómo pueden ayudarte a resolver problemas del mundo real de manera eficiente.