Aprende leyendo en orden

Bucles — procesar archivos uno por uno con for

Este artículo forma parte del Curso de Linux, con el que dominarás desde cero habilidades prácticas de Linux, desde los comandos básicos hasta los scripts de shell.
Recorre una lista de archivos con for f in *.txt, repite con condición usando while [ "$i" -le 3 ] y until, salta valores vacíos con continue y detente en un límite con break — escrito y practicado en una terminal del navegador, ilustrado.

Procesar una lista en orden — for

for toma los valores que le das uno a uno y ejecuta el mismo trabajo sobre cada uno.

La forma es for v in a b c; do ... done, donde v toma a, luego b y luego c por turnos.

Lo que va entre do y done es el cuerpo que se repite.

Puedes enumerar los valores directamente, usar un patrón de archivo como *.txt o pasar la salida de $(...) de un comando.

Escribe for f in *.txt y cada archivo .txt del directorio actual entra en f por turnos, así que puedes escribir trabajo por archivo.

Usar $(...) como en for line in $(cat list.txt) te permite recorrer la salida de un comando.

Así es como escribes resúmenes de una lista de archivos o procesamiento por lotes sobre varios archivos.

for env in dev stg prod; do        # procesa los valores enumerados por turnos
  echo "deploying to $env"
done
for f in *.sh; do                  # procesa los archivos .sh por turnos
  echo "script: $f"
done
Cómo gira un bucle for
for f in *.txtEjecuta cuerpo(do … done)siguiente → ffin en donesi no queda ningunorepite por cada elemento
for saca elementos de la lista hacia f uno a uno y ejecuta el cuerpo, luego termina en done cuando se acaban los elementos.
SyntaxSignificadoExample
for v in a b c; do … doneprocesa los valores enumerados por turnosfor v in dev stg prod; do echo $v; done
for f in *.txt; do …procesa los archivos que coinciden por turnosfor f in *.txt; do wc -l "$f"; done
for x in $(cmd); do …procesa la salida de un comando por turnosfor d in $(ls); do echo $d; done
do … doneinicio y fin del cuerpo del buclefor v in a b; do echo $v; done

Escribe un script que recorra una lista de archivos y sume los conteos.

① Abre count-lines.sh con vi count-lines.sh, pulsa i para entrar en modo de inserción y escribe #!/bin/sh en la primera línea.

② Dentro del script, crea algunos archivos de ejemplo, recorre un patrón de archivo con for, cuenta las líneas de cada archivo una a una e imprime el total.

③ Pulsa Esc, guarda con :wq y luego añade permiso de ejecución.

④ Ejecuta el script y confirma que se imprimen cada archivo y el total.

⑤ Si no sabes qué escribir, copia el texto del panel de respuesta y pégalo en el modo de inserción de vi. (Ejecútalo correctamente para revelar la explicación.)

Linux console
0 / 3 completado(s)
Loading Linux Terminal...

Repetir con condición — while / until

while repite mientras la condición sea verdadera.

Como en while [ "$i" -lt 3 ]; do ... done, incrementas un contador dentro del cuerpo para acercarte al final.

until es lo contrario — repite hasta que la condición se vuelve verdadera.

Sirve para trabajo donde el número de rondas no está fijado de antemano.

i=1
while [ "$i" -le 3 ]; do          # repite mientras i sea 3 o menos
  echo "try $i"
  i=$((i + 1))
done                              # try 1 / try 2 / try 3
i=1
until [ "$i" -gt 3 ]; do          # repite hasta que la condición se vuelva verdadera
  echo "i=$i"
  i=$((i + 1))
done                              # i=1 / i=2 / i=3
while frente a until
while [ i ≤ 3 ]condición trueejecuta cuerpountil [ i > 3 ]condición falseejecuta cuerpowhile: repite mientras trueuntil: repite hasta true
while repite el cuerpo mientras la condición es verdadera; until lo repite hasta que la condición se vuelve verdadera. Ambos avanzan un contador en el cuerpo para acercarse al final.
SyntaxSignificadoExample
while [ cond ]; do … donerepite mientras la condición es verdaderawhile [ "$i" -lt 3 ]; do …; done
until [ cond ]; do … donerepite hasta que la condición se vuelve verdaderauntil [ -f done.flag ]; do …; done

Escribe un script de reintento que repita el trabajo mientras cuenta las rondas.

① Abre retry.sh con vi retry.sh, pulsa i para entrar en modo de inserción y escribe #!/bin/sh en la primera línea.

② Prepara una variable contador, recorre con while hasta un límite mientras imprimes el número de intento e incrementa el contador dentro del cuerpo.

③ Confirma que reescribir el mismo trabajo como until [ "$i" -gt "$max" ] da el mismo resultado.

④ Pulsa Esc, guarda con :wq y luego añade permiso de ejecución.

⑤ Ejecuta el script y confirma que repitió el número de veces indicado.

⑥ Si no sabes qué escribir, copia el texto del panel de respuesta y pégalo en el modo de inserción de vi.

Linux console
0 / 3 completado(s)
Loading Linux Terminal...

Controlar un bucle for — break / continue

Incluso a mitad de un bucle for, puedes cambiar el flujo con break y continue.

continue salta el resto de esa ronda y pasa al siguiente elemento, mientras que break termina el bucle en sí.

Combínalos con una condición como en if [ condición ]; then continue; fi o if [ condición ]; then break; fi para saltar los elementos que no necesitas o detenerte cuando ya tienes suficiente.

for n in 1 2 3 4 5; do
  if [ "$n" -eq 3 ]; then continue; fi  # salta 3
  if [ "$n" -eq 5 ]; then break; fi     # sale en 5
  echo "n=$n"
done                                    # n=1 / n=2 / n=4
flujo de break / continue en for
n=1ejecuta cuerpoimprime n=1n=2ejecuta cuerpoimprime n=2n=3continuesalta resto, siguen=4ejecuta cuerpoimprime n=4n=5breaktermina el bucleal siguiente elementocontinue: salta esta rondabreak: sale del bucle
for ejecuta el cuerpo en orden desde n=1. En n=3 el continue salta el resto y sigue, y en n=5 el break termina el bucle en sí (la salida es n=1 / n=2 / n=4).
SyntaxSignificadoExample
continuesalta esta ronda y pasa a la siguienteif [ -z "$x" ]; then continue; fi
breaksale del bucle a mitad de caminoif [ "$n" -gt 100 ]; then break; fi

Escribe un script de recolección que salte los valores vacíos y se detenga en un límite.

① Abre collect.sh con vi collect.sh, pulsa i para entrar en modo de inserción y escribe #!/bin/sh en la primera línea.

② Recorre una lista de valores con for, salta los valores vacíos o no deseados con continue y sal del bucle con break cuando alcances el límite.

③ Pulsa Esc, guarda con :wq y luego añade permiso de ejecución.

④ Ejecuta el script y confirma los valores saltados y el punto donde se detuvo.

⑤ Si no sabes qué escribir, copia el texto del panel de respuesta y pégalo en el modo de inserción de vi.

Linux console
0 / 3 completado(s)
Loading Linux Terminal...

Controlar un bucle while — break / continue

Además de la comprobación de condición en while, usar break y continue te permite detenerte antes o saltar una ronda.

continue salta esa ronda y vuelve a la comprobación de condición, mientras que break sale del bucle sin esperar a la condición.

Cuidado aquí: si no colocas la actualización del contador al inicio del cuerpo (antes de continue), la ronda saltada no lo actualizará y el bucle nunca terminará.

i=0
while [ "$i" -lt 10 ]; do
  i=$((i + 1))                          # avanza al inicio
  if [ "$i" -eq 3 ]; then continue; fi  # salta la 3ª ronda
  if [ "$i" -eq 6 ]; then break; fi     # sale en la 6ª ronda
  echo "attempt $i"
done                                    # attempt 1 / 2 / 4 / 5
flujo de break / continue en while
i=1ejecuta cuerpoattempt 1i=2ejecuta cuerpoattempt 2i=3continuevuelve a comprobari=4ejecuta cuerpoattempt 4i=5ejecuta cuerpoattempt 5i=6breaktermina el buclea la siguiente rondacontinue: vuelve a comprobarbreak: sale del bucle
while ejecuta el cuerpo mientras la condición es verdadera, avanzando i en 1 cada vez. En i=3 el continue vuelve a la comprobación de condición, y en i=6 el break termina el bucle sin esperar a la condición (la salida es attempt 1 / 2 / 4 / 5).
SyntaxSignificadoExample
continuesalta esta ronda, vuelve a comprobarif [ $((i % 3)) -eq 0 ]; then continue; fi
breaksale del bucle sin esperar a la condiciónif [ "$found" -ge 4 ]; then break; fi
dónde actualizar el contadoractualízalo antes de continuepon i=$((i + 1)) al inicio del cuerpo

Escribe un script de escaneo que recorra con while, salte las rondas que no necesita y se detenga cuando tenga el número de elementos que necesita.

① Abre scan.sh con vi scan.sh, pulsa i para entrar en modo de inserción y escribe #!/bin/sh en la primera línea.

② Prepara un contador, recorre con while hasta un límite y avanza el contador en 1 al inicio del cuerpo.

③ Salta las rondas que cumplen cierta condición con continue y sal del bucle con break cuando alcances el número de elementos que necesitas.

④ Pulsa Esc, guarda con :wq y luego añade permiso de ejecución.

⑤ Ejecuta el script y confirma las rondas saltadas y el punto donde se detuvo.

⑥ Si no sabes qué escribir, copia el texto del panel de respuesta y pégalo en el modo de inserción de vi.

Linux console
0 / 3 completado(s)
Loading Linux Terminal...
QUIZ

Verificación de conocimientos

Responde cada pregunta una a una.

Pregunta 1¿Sobre qué itera for f in *.txt; do ... done?

Pregunta 2¿Qué palabra clave repite mientras la condición es verdadera?

Pregunta 3¿Cuál salta solo esa ronda y pasa a la siguiente?