Bash Loops con ejemplos

- 4322
- 88
- Sra. María Teresa Rentería
Listo para sumergirse en Bash Looping? Con la popularidad de Linux como un sistema operativo libre y armado con la potencia de la interfaz de la línea de comandos bash, uno puede ir más lejos, codificando bucles avanzados desde la línea de comandos o dentro de los scripts bash.
Aprovechando este poder, se puede manipular cualquier documento, cualquier conjunto de archivos o implementar algoritmos avanzados de casi cualquier tipo y sabor. Es poco probable que te encuentres con cualquier limitación si usa bash como base para sus secuencias de comandos, y los bucles bash forman una parte poderosa de esto.
Dicho esto, los bucles bash a veces pueden ser complicados en términos de sintaxis y el conocimiento circundante es primordial. Hoy presentamos con usted un conjunto de ejemplos de bucle de bash para ayudarlo a aumentar rápidamente y convertirse en un bucle de bash competente! Empecemos!
En este tutorial aprenderás:
- Como Bash
para
,mientras
yhasta
Trabajo de bucles basados, con ejemplos - Cómo BASH requiere la finalización de las declaraciones de inicio de bucle antes de la sección Do ... HETRO del bucle puede seguir y cómo esto se relaciona con IF y otras declaraciones
- Cómo implementar bucles de bash avanzados básicos y medianos
- Cómo funcionan las subshells y cómo se pueden usar dentro de las declaraciones de alcance del bucle de bash
- Cómo comenzar a codificar los bucles a la defensiva, evitando los errores en la salida
- Cómo codificar
fraseador
(un término común utilizado entre los desarrolladores de bash) en la línea de comando versus implementar el mismo código en un script bash - Cómo
;
El idioma de sintaxis es un asunto importante cuando se trata de codificar los bucles Bash, tanto en la línea de comandos como en los scripts

Ejemplos de bucles bash
- Comencemos con un básico
para
bucle:
Copiar$ para i en $ (SEQ 1 5); hacer eco $ i; hecho 1 2 3 4 5
Como puedes ver, básico
para
Los bucles en Bash son relativamente simples de implementar. Aquí están los pasos:para: Indica que queremos iniciar un nuevo bucle basado
i: Una variable que usaremos para almacenar el valor generado por la cláusula dentro de laen
Palabra clave (a saber, la secuencia justo debajo)
$ (SEQ 1 5): Esto está ejecutando un comando dentro de otra subhorro.Para comprender cómo funciona esto, considere este ejemplo:
Copiar$ seq 1 5 1 2 3 4 5
Básicamente, el
ps
La sintaxis se puede usar cuando (y donde sea!) quieres comenzar una nueva subshell. Esta es una de las características más poderosas de la cáscara de Bash. Considere por ejemplo:
CopiarPrueba de $ Cat.txt 1 2 $ echo "$ (prueba de gato.txt | cabeza -n1) "1
Como puede ver, aquí la subshell ejecutó 'prueba de gato.txt | head -n1 '(' head -n1 'selecciona solo la primera línea) y luego se hizo eco de la salida de esa subshell.
Continuemos analizando nuestro bucle for arriba:
;: Esto es muy importante. En Bash, cualquier "acción", como por ejemplo un arranque de bucle 'para', o una prueba de instrucción 'si', o un bucle de tiempo, etc. necesita ser terminado con un ';'. Por lo tanto, la ';' está aquí * antes * el hacer, no después. Considere esto muy similar si el ejemplo:
Copiar$ if ["a" == "a"]; Entonces hacer eco "Sí!"; fi si!
Observe cómo de nuevo el
;
es antes delentonces
, no después de. Por favor, no permita que esto lo confunda mientras se seca o mientras bucle, si se declaran, etc. Solo recuerde que cada acción debe finalizarse antes de cualquier acción nueva y, por lo tanto,para
osi
necesita ser terminado antes de la siguiente acción que es 'entonces' en el ejemplo de la declaración if, yhacer
En el bucle for arriba!Finalmente tenemos:
hacer: Indicando que
para
Lo que viene antes… hacer…
Lo que viene en lo sucesivo. Tenga en cuenta nuevamente que esta palabra de acción es después del cierre;
Se utiliza para cerrar la declaración de apertura de bucle para el bucle.
echo $ i: Aquí generamos el valor almacenado en eli
variable ($ I
)
;: Terminar la instrucción ECHO (terminar cada acción)
hecho: Indica que este es el final de nuestro bucle - Tomemos este mismo ejemplo pero escríbelo de manera diferente:
Copiar$ para i en 1 2 3 4 5; hacer eco $ i; hecho 1 2 3 4 5
Puede ver ahora cómo se relaciona esto con el ejemplo anterior; Es el mismo comentario, aunque aquí no usamos una subshell para generar una secuencia de entrada para nosotros, lo especificamos manualmente nosotros mismos.
¿Esto aparece una carrera sobre los posibles usos un poco?? Entonces debería 🙂 hagamos algo genial con esto ahora.
- Aumento de la complejidad de nuestro bucle para incluir archivos:
Copiar$ LS 1.txt 2.txt 3.txt 4.txt 5.TXT
Copiar$ head -n1 *.txt ==> 1.TXT <== 1 ==> 2.TXT <== 1 ==> 3.TXT <== 1 ==> 4.TXT <== 1 ==> 5.TXT <== 1
Copiar$ para i en $ (ls *.TXT); hacer gato "$ i" | cabeza -n1; hecho 1 1 1 1 1
¿Puedes averiguar lo que está pasando aquí?? Mirando las nuevas partes de esto para bucle, vemos:
$ (LS *.TXT): Esto enumerará todos los archivos TXT en el directorio actual y tenga en cuenta que el nombre de esos archivos se almacenará en eli
variable, un archivo per/para cada bucle elpara
El bucle se ejecutará.En otras palabras, la primera vez que ocurre el bucle (la parte entre hacer y hecho),
$ I
contendrá1.TXT
. La próxima carrera$ I
contendrá2.TXT
etcétera.gato "$ i" | cabeza -n1: Aquí tomamos el
$ I
variable (como hemos visto esto será1.TXT
, seguido por2.TXT
etc.) y Cat ese archivo (mostrarlo) y tomar la primera línea de la mismacabeza -n1
. Así, 5 veces1
es salida, ya que esa es la primera línea en los 5 archivos como podemos ver desde el anteriorcabeza -n1
a través de todas .archivos txt. - ¿Qué tal uno muy complejo ahora??
Copiar$ Tail -n1 *.txt ==> 1.TXT <== 1 ==> 2.TXT <== 2 ==> 3.TXT <== 3 ==> 4.TXT <== 4 ==> 5.TXT <== 5
Copiar$ para i en $ (ls *.txt 2>/dev/null); hacer echo -n "$ (cola -n1 $ i)"; Echo "de $ i !"; hecho 1 de 1.TXT ! 2 de 2.TXT ! 3 de 3.TXT ! 4 de 4.TXT ! 5 de 5.TXT !
¿Puedes hacer ejercicio lo que está pasando aquí??
Analicémoslo paso a paso.
para yo en : Ya sabemos esto; empezar de nuevo
para
bucle, asigne la variable I a lo que sea que siga en elen
cláusula
$ (LS *.txt 2>/dev/null): Lo mismo que el comando anterior; Enumere todos los archivos TXT, pero esta vez con un poco de protección definitiva para evitar errores en su lugar. Mirar:$ para i en $ (ls i.hacer.no.existir); hacer eco "solo probando la no existencia de archivos"; hecho ls: no puedo acceder 'i.hacer.no.existir ': no hay dicho archivo o directorio
No es muy profesional! De este modo;
$ para i en $ (ls i.hacer.no.existir 2>/dev/null); hacer eco "solo probando la no existencia de archivos"; hecho
Esta declaración genera ninguna salida.
Continuemos nuestro análisis:
; hacer: Termine la declaración inicial de bucle for para bucle, comience la sección do ... realizada de nuestra definición de bucle
echo -n "$ (cola -n1 $ i)";: En primer lugar, el-norte
representa No salga a la nueva línea de salida al final de la salida solicitada.A continuación, estamos tomando la última línea de cada archivo. Tenga en cuenta cómo hemos optimizado nuestro código desde arriba? i.mi. en lugar de hacer
archivo de gato.txt | cola -n1
uno simplemente puede hacercola -n1 archivo.TXT
- una taquigrafía que los nuevos desarrolladores de Bash pueden perder fácilmente. En otras palabras, aquí estamos simplemente imprimiendo1
(la última línea en 1.txt) seguido inmediatamente por2
para2.TXT
etc.
Como nota al margen, si no especificamos el comando de eco de seguimiento, la salida simplemente habría sido
12345
Sin ninguna línea nueva:
Copiar$ para i en $ (ls *.txt 2>/dev/null); hacer echo -n "$ (cola -n1 $ i)"; hecho 12345 $
Observe cómo incluso la última nueva línea no está presente, de ahí la salida antes de la solicitud
ps
devoluciones.Finalmente tenemos
Echo "de $ i !";
(mostrándonos elde 1.TXT !
salida) y el cierre del bucle por elhecho
.Confío en que ahora puedes ver cuán poderoso es esto y cuánto control se puede ejercer sobre archivos, contenido de documentos y más!
Generemos una larga cadena aleatoria con un bucle de tiempo siguiente siguiente! Divertido?
- Usando un bucle de tiempo para generar una cadena aleatoria:
Copiar$ Random = "$ (fecha +%s%n | corte -b14-19)" $ count = 0; Myrandom =; mientras que es cierto; do count = $ [$ count + 1]; if [$ count -gt 10]; luego romper; fi; Myrandom = "$ myrandom $ (echo" $ random "| sed 's |^\ (.\).*| \ 1 | ') "; hecho; echo" $ myrandom "6421761311
Que parece complejo! Analicémoslo paso a paso. Pero primero, veamos cómo se vería esto dentro de un guión de Bash.
- Ejemplo de la misma funcionalidad, implementada dentro de un script bash:
CopiarPrueba de $ Cat.sh #!/bin/bash random = "$ (fecha +%s%n | CUT -B14-19)" Conde = 0 myrandom = while true; do count = $ [$ count + 1] if [$ count -gt 10]; luego rompa fi myrandom = "$ myrandom $ (echo" $ aleatory "| sed 's |^\ ((.\).*| \ 1 | ') "hecho echo" $ myrandom "
Prueba de $ chmod +x.sh $ ./prueba.SH 1111211213 $ ./prueba.SH 1212213213
Es bastante sorprendente a veces que un código de bucle bash tan complejo se puede mover tan fácilmente a un 'una sola línea' (un término que los desarrolladores de bash usan para referirse a lo que es realidad un pequeño script pero implementado directamente desde la línea de comandos, generalmente en un Líneas individuales (o como máximas).
Comencemos a analizar nuestros dos últimos ejemplos, que son muy similares. Las pequeñas diferencias en el código, especialmente alrededor del idioma ';'; se explican en Ejemplo 7 abajo:
Random = "$ (fecha +%s%n | Cut -B14-19)" En la línea 4: esto toma (usando
Cortar -B14-19
) Los últimos 6 dígitos del tiempo actual de la época (el número de segundos que han pasado desde el 1 de enero de 1970) según lo informado porfecha +%s%n
y asigna que generó una cadena a la variable aleatoria, estableciendo así una entropía semi-aleatoria al grupo aleatorio, en términos simples "haciendo que el grupo aleatorio sea algo más aleatorio".
Recuento = 0 En la línea 6: configure elCONTAR
variable a0
Myrandom = en la línea 7: configure elMirandom
variable a 'vacío' (sin valor asignado)
Mientras ... hacer ... hecho Entre la línea 9 y la línea 15: esto debería estar claro ahora; Comience un bucle de tiempo, ejecute el código entre las cláusulas DO ...
verdadero: y mientras la declaración que siga el 'while' se evalúa como verdadero, el bucle continuará. Aquí la declaración es 'verdadera', lo que significa que este es un bucle indefinido, hasta unromper
Se da declaración.
Count = $ [$ count + 1] En la línea 10: aumentar nuestroCONTAR
variable por1
if [$ count -gt 10]; entonces En la línea 11: una declaración IF para verificar si nuestra variable es mayor entonces-GT 10
, Y si es así, ejecute el entonces ..FI
parte
romper En la línea 12: esto romperá el indefinido mientras el bucle (yo.mi. cuandoCONTAR
es mayor entonces10
el bucle terminará)
Myrandom = ".. en la línea 14: vamos a asignar un nuevo valor aMirandom
$ Myrandom En la línea 14: Primero, tome lo que ya tenemos dentro de esta variable, en otras palabras, agregaremos algo al final de lo que ya está allí, y esto para cada bucle posterior
$ (echo "$ random" | sed 's |^\ (.\).*| \ 1 | ') en la línea 14: esta es la parte que se agrega cada vez. Básicamente, se hace eco elALEATORIO
variable y toma el primer carácter de esa salida utilizando una expresión regular compleja en SED. Puedes ignorar esa parte si lo quieres, básicamente dice "Tomar el primer personaje del$ Random
salida variable y descartar todo lo demás "Puede ver cómo la salida (por ejemplo
1111211213
) es generado; Un personaje (de izquierda a derecha) en ese momento, usando el bucle While, que boques10
veces como resultado delCONTAR
Comprobación de contador de variables.Entonces, ¿por qué la salida es a menudo en formato de
1
,2
,3
y menos de otros números? Esto es porque elALEATORIO
La variable devuelve una variable semi-azar (basada en elAleatorio = ..
semilla) que se encuentra en el rango de 0 a 32767. Por lo tanto, a menudo este número comenzará con 1, 2 o 3. Por ejemplo, 10000-19999 volverá en1
etc. Como el primer carácter de la salida siempre es tomado por el SED! - Un breve script para resaltar la posibilidad de organizar (o estilo) el código de bucle de bash de manera diferente sin usar el
;
modismo.Necesitamos aclarar las pequeñas diferencias del script bash versus el script de línea de comandos de una línea.
NOTA
Tenga en cuenta que en el script bash (prueba.sh) no hay tantos;
modismos. Esto se debe a que ahora hemos dividido el código en varias líneas y un;
es no requerido cuando hay un carácter EOL (fin de línea) en su lugar. Tal personaje (nueva línea o retorno de carro) no es visible en la mayoría de los editores de texto, pero se explica por sí mismo si piensa en el hecho de que cada comando está en una línea separada.También tenga en cuenta que podría colocar el
hacer
cláusula delmientras
bucle en la siguiente línea también, de modo que se vuelve innecesario incluso usar el;
allá.
Copiar$ Cat Test2.sh #!/bin/bash para i en $ (seq 1 3) hacer eco "... bucle ... $ yo ..." Hecho
ps ./Test2.sh ... bucle ... 1 ... bucle ... 2 ... bucle ... 3 ..
Personalmente prefiero el estilo de sintaxis dado en Ejemplo 6, Como parece más claro cuál es la intención del código escribiendo la declaración de bucle en su totalidad en una línea (igual a otros lenguajes de codificación), aunque las opiniones y los estilos de sintaxis difieren por desarrollador, o por comunidad de desarrollador.
- Finalmente, echemos un vistazo a un bucle Bash 'hasta':
Copiar$ Nr = 0; hasta [$ nr -eq 5]; hacer echo "$ nr"; Nr = $ [$ nr + 1]; hecho 0 1 2 3 4
Analicemos este ejemplo:
NR = 0: Aquí establece una variable nombrada
Nr
, a cero
hasta: Comenzamos nuestro bucle 'hasta'
[$ Nr -eq 5]: Este es nuestrosi
condición o mejor nuestrahasta
condición. yo digosi
Como la sintaxis (y el trabajo) es similar a la del comando de prueba, yo.mi. el comando de subestimación que se usa ensi
declaraciones. En bash, el comando de prueba también puede estar representado por un solo["]
soportes. El$ Nr -eq 5
prueba medias; Cuando nuestra variableNr
alcanza las 5, entonces la prueba se volverá verdadera, a su vez haciendo elhasta
End de bucle como la condición coincide (otra forma de leer esto es como 'hasta que verdadero' o 'hasta que nuestra variable nr sea igual a 5'). Tenga en cuenta que una vez que NR es 5, el código de bucle ya no se ejecuta, por lo tanto, 4 es el último número que se muestra.
;: Terminar nuestra declaración hasta que se explicó anteriormente
hacer: Comience nuestra cadena de acción que se ejecutará hasta que la declaración probada se vuelva verdadera/válida
echo "$ nr;":eco
fuera el valor actual de nuestra variableNr
Nr = $ [$ nr + 1];: Aumente nuestra variable por uno. Elps
El método de cálculo es específico de Bash
hecho: Terminar nuestra cadena de acción/código de bucleComo puede ver, mientras que los bucles son de naturaleza muy similar, aunque de hecho son opuestos. Mientras que los bucles se ejecutan siempre que algo sea verdadero/válido, mientras que hasta que los bucles se ejecuten siempre que algo sea 'no válido/verdadero todavía'. A menudo son intercambiables al invertir la condición.
Conclusión
Confío en que puedas comenzar a ver el poder de la fiesta, y especialmente para, mientras que Bash loops. Solo hemos arañado la superficie aquí, y puedo volver más tarde con más ejemplos avanzados. Mientras tanto, déjenos un comentario sobre cómo está utilizando bucles bash en sus tareas o scripts diarios. Disfrutar!
Tutoriales de Linux relacionados:
- Bucles anidados en guiones Bash
- Mastering Bash Script Loops
- Una introducción a la automatización, herramientas y técnicas de Linux
- Cosas para instalar en Ubuntu 20.04
- Scripting de bash y gestión de procesos multiprocesos en el ..
- Cosas que hacer después de instalar Ubuntu 20.04 fossa focal Linux
- Sistema colgado de Linux? Cómo escapar a la línea de comando y ..
- Manejo de la entrada del usuario en scripts bash
- Mint 20: Mejor que Ubuntu y Microsoft Windows?
- Cosas para instalar en Ubuntu 22.04