5. Bucles y Estructuras de Repetición

Los bucles permiten ejecutar un conjunto de instrucciones varias veces. Son esenciales en automatización, análisis de archivos, procesado de datos, monitoreo y en general cualquier script útil.

En Bash disponemos de varias estructuras de repetición: for, while, until y control de bucles mediante break y continue.


1. Bucle for

Ideal para iterar sobre listas, rangos o elementos concretos.

1.1. Iterar sobre una lista

Sintaxis:





for var in elemento1 elemento2 elemento3; do
    comandos
done

Ejemplo:





for animal in perro gato loro; do
    echo "Animal: $animal"
done

Salida:





Animal: perro
Animal: gato
Animal: loro

1.2. Iterar sobre un rango





for i in {1..5}; do
    echo "Número: $i"
done

Salida:





Número: 1
Número: 2
Número: 3
Número: 4
Número: 5

1.3. Iterar sobre archivos





for archivo in *.txt; do
    echo "Procesando $archivo"
done

Muy útil para automatizar tareas sobre lotes de archivos.


2. Bucle while

Ejecuta instrucciones mientras se cumpla una condición.

Sintaxis:





while [ condición ]; do
    comandos
done

Ejemplo:





contador=1
while [ $contador -le 5 ]; do
    echo "Contador: $contador"
    contador=$((contador + 1))
done

2.1. Leer archivo línea a línea

Excelente para procesar logs o datos estructurados.





while read linea; do
    echo "$linea"
done < archivo.txt

3. Bucle until

Es lo inverso a while: ejecuta hasta que se cumpla una condición.

Sintaxis:





until [ condición ]; do
    comandos
done

Ejemplo:





contador=1
until [ $contador -gt 5 ]; do
    echo "Contador: $contador"
    contador=$((contador + 1))
done

Hace lo mismo que el ejemplo de while, pero con lógica inversa.


4. Control del Flujo: break y continue

break

Termina el bucle antes de tiempo.

Ejemplo:





for i in {1..10}; do
    if [ $i -eq 5 ]; then
        break
    fi
    echo "i = $i"
done

Salida:





i = 1
i = 2
i = 3
i = 4

continue

Salta a la siguiente iteración sin terminar el bucle.

Ejemplo:





for i in {1..5}; do
    if [ $i -eq 3 ]; then
        continue
    fi
    echo "i = $i"
done

Salida:





i = 1
i = 2
i = 4
i = 5

5. Bucles Anidados

Se puede meter un bucle dentro de otro.

Ejemplo:





for i in {1..3}; do
    for j in {1..2}; do
        echo "i=$i, j=$j"
    done
done

6. Ejemplos Aplicados

Ejemplo 1: Contador simple





#!/bin/bash

for i in {1..10}; do
    echo "Número: $i"
done

Ejemplo 2: Procesar todos los .log





#!/bin/bash

for log in *.log; do
    echo "Analizando $log..."
done

Ejemplo 3: Ping a una subred





#!/bin/bash

for i in {1..254}; do
    ping -c 1 192.168.1.$i >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "192.168.1.$i está activo"
    fi
done

Ejemplo 4: Leer archivo línea a línea





#!/bin/bash

while read linea; do
    echo "Línea: $linea"
done < usuarios.txt

Ejercicios propuestos

Ejercicio 1:
Crear un script cuenta.sh que muestre los números del 1 al 20 usando for.

Ejercicio 2:
Crear un script files.sh que liste todos los archivos del directorio actual y muestre cuántos hay al final.

Ejercicio 3:
Crear un script ping.sh que pida una IP base (por ejemplo 192.168.1) y haga ping del .1 al .10, mostrando solo los que respondan.

Ejercicio 4:
Crear un script leer.sh que lea un archivo de texto pasado como parámetro y muestre cada línea precedida del número de línea:

Ejemplo:





1: línea uno
2: línea dos
3: línea tres

Soluciones

✅ Ejercicio 1 — cuenta.sh

Enunciado:
Crear un script cuenta.sh que muestre los números del 1 al 20 usando for.

💡 Solución:





#!/bin/bash
# Script: cuenta.sh
# Muestra los números del 1 al 20

for i in {1..20}; do
    echo "$i"
done

Salida esperada:





1
2
3
...
20

✅ Ejercicio 2 — files.sh

Enunciado:
Crear un script files.sh que liste todos los archivos del directorio actual y muestre cuántos hay al final.

💡 Solución sencilla (con ls y wc -l):





#!/bin/bash
# Script: files.sh
# Lista los archivos del directorio actual y muestra cuántos hay

echo "Archivos en el directorio actual:"
ls

echo
total=$(ls | wc -1)
echo "Total de entradas: $total"

Nota: ls lista tanto archivos como directorios. Para un curso inicial está bien.

💡 Versión algo más “didáctica” con for y contador:





#!/bin/bash
# Script: files.sh
# Recorre las entradas del directorio actual y las cuenta

contador=0

echo "Entradas en el directorio actual:"
for item in *; do
    echo "$item"
    contador=$((contador + 1))
done

echo
echo "Total de entradas: $contador"

✅ Ejercicio 3 — ping.sh

Enunciado:
Crear un script ping.sh que pida una IP base (por ejemplo 192.168.1) y haga ping del .1 al .10, mostrando solo las IP que respondan.

💡 Solución:





#!/bin/bash
# Script: ping.sh
# Hace ping a una serie de IPs de la misma red (del .1 al .10)

read -p "Introduce la IP base (ej: 192.168.1): " base

for i in {1..10}; do
    ip="$base.$i"
    ping -c 1 -W 1 "$ip" >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "$ip está ACTIVA"
    else
        echo "$ip no responde"
    fi
done

Si quieres que solo muestre las activas, quitas el else:





#!/bin/bash
# Solo muestra las IP que responden

read -p "Introduce la IP base (ej: 192.168.1): " base

for i in {1..10}; do
    ip="$base.$i"
    ping -c 1 -W 1 "$ip" >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "$ip está ACTIVA"
    fi
done

✅ Ejercicio 4 — leer.sh

Enunciado:
Crear un script leer.sh que lea un archivo de texto pasado como parámetro y muestre cada línea precedida del número de línea:

Ejemplo:





1: línea uno
2: línea dos
3: línea tres

💡 Solución:





#!/bin/bash
# Script: leer.sh
# Muestra un archivo línea a línea con número de línea

if [ $# -ne 1 ]; then
    echo "Uso: $0 archivo"
    exit 1
fi

archivo="$1"

if [ ! -f "$archivo" ]; then
    echo "El archivo '$archivo' no existe o no es un archivo regular."
    exit 1
fi

num_linea=1
while read linea; do
    echo "$num_linea: $linea"
    num_linea=$((num_linea + 1))
done < "$archivo"

Ejemplo de uso:





./leer.sh notas.txt

Salida:





1: primera línea del archivo
2: segunda línea del archivo
3: tercera línea...