Antes de comenzar con este tema, debemos tener en cuenta algo muy importante:
NOTA: Las estructuras iterativas pueden generar bucles infinitos, por lo que deben escribirse con mucho cuidado.
En Bash, también la sintaxis del bucle for es muy similar a la de muchos lenguajes de programación:
for (( inicio; condición; incremento )); do
# código
done
O bien:
for (( inicio; condición; incremento ))
do
# código
done
Por ejemplo, mostrar los números del 1 al 10:
for (( i=1; i<=10; i++ )); do
echo $i
done
Una variante de este bucle es el de for-in con el que se pueden recorrer directorios, rangos, arrays, etcétera:
for elemento in rango; do
# código
done
Recuerda que los rangos de números se escriben como {5..68} y los de letras como {b..y}. Entonces el ejemplo anterior se podría reescribir así:
for i in {1..10}; do
echo $i
done
En cuanto a los arrays, la expresión para recorrerlo es con {$[array][*]}. He aquí un ejemplo:
arboles=("Araucaria" "Cedro" "Roble" "Eucalipto" "Pino")
for arbol in ${arboles[*]}; do
echo $arbol
done
Para conocer el contenido de un directorio simplemente se especifica con un asterisco (*) al final de la ruta, para abarcar todos sus archivos y subdirectorios:
for elem in /home/*; do
echo $elem
done
La estructura del bucle while no es muy diferente a la de otros lenguajes:
valor_inicial
while [[ condición ]]; do
# código
# incremento
done
Es muy importante recordar establecer un valor inicial y un incremento para evitar bucles infinitos. El incremento se puede expresar como ((valor_inicial++)).
Siguiendo el ejemplo anterior, con el bucle while sería así:
i=1
while [[ $i -le 10 ]]; do
echo $i
((i++))
done
Muchos lenguajes de programación cuentan con el bucle do-while, pero esto no existe en Bash. En cambio sí cuenta con una estructura llamada until (hasta que) que, al contrario que la de while, ejecuta el código mientras la condición sea falsa, es decir, hasta que la condición se cumpla. En otras palabras, la condición en until es contraria a la que sería en while.
La sintaxis es:
valor_inicial
until [[ condición ]]; do
# código
# incremento
done
Aplicándolo al ejemplo que venimos viendo:
i=1
until [[ $i -gt 10 ]]; do
echo $i
((i++))
done
Vemos que la condición pasa de ser menor o igual a 10 (-le 10) a ser directamente mayor que 10 (-gt 10).
Nuevamente, al igual que con otros lenguajes, Bash cuenta las palabras reservadas break que nos permite salir del bucle y continue que nos permite omitir una iteración, bajo ciertas condiciones.
NOTA: En la estructuracaseno se utilizabreakal final de cada opción.
Veamos en el siguiente ejemplo una aplicación de break. En este caso se muestran solamente los números del 1 al 7 porque el bucle se interrumpe al llegar a este valor:
i=1
while [[ $i -le 10 ]]; do
if [[ $i -eq 7 ]]; then
break
fi
echo $i
((i++))
done
En cuanto a continue, en el siguiente caso se muestran todos los números menos el 4:
i=0
while [[ $i -le 10 ]]; do
((i++))
if [[ $i -eq 4 ]]; then
continue
fi
echo $i
done
Aquí hay algo muy importante a tener en cuenta: el contador comienza desde 0 en vez de 1 y se incrementa antes del if.
NOTA: En el caso de continue, las líneas que le siguen serán ignoradas porque el programa saltará directamente al inicio del bucle. Por lo tanto, es recomendable que el incremento ocurra antes del condicional para evitar un bucle infinito.
Además es necesario sustituir -le por -lt para que se imprima hasta el número 10 (de lo contrario, se haría una iteración más y se incluiría el 11).
Y por supuesto, también se pueden combinar ambos términos en un mismo código:
i=0
while [[ $i -le 10 ]]; do
((i++))
if [[ $i -eq 4 ]]; then
continue
fi
echo $i
if [[ $i -eq 7 ]]; then
break
fi
done
Al ejecutarlo se muestran únicamente los números del 1 al 7, salvo el 4.
for simple, crear un programa que muestre los números enteros comprendidos entre 28 y 51 incluidos.for-in, crear un array con los nombres analía, bernardo, catalina, david, ester, fabricio, gabriela y héctor, y que los muestre con todas las letras en mayúsculas.while, imprimir todos los números enteros entre 105 y 147 que sean pares (Pista: usar el operador de módulo).until, mostrar todos los enteros entre 39 y 16 (no incluido) en orden descendente, y que al final imprima la cantidad total de números.for-in, el condicional case y continue para imprimir el rango entre la A y la Z, excepto las letras D, J, N y W.for-in, el condicional if y break para imprimir todas las letras de la k a la v, interrumpiendo el bucle en la letra t.