Bash Loops con ejemplos

Bash Loops con ejemplos

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 y hasta 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
Bash Scripting - Bash Loops con ejemplos

Ejemplos de bucles bash

  1. Comencemos con un básico para bucle:
    $ para i en $ (SEQ 1 5); hacer eco $ i; hecho 1 2 3 4 5
    Copiar

    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 la en 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:

    $ seq 1 5 1 2 3 4 5
    Copiar

    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:

    Prueba de $ Cat.txt 1 2 $ echo "$ (prueba de gato.txt | cabeza -n1) "1
    Copiar

    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:

    $ if ["a" == "a"]; Entonces hacer eco "Sí!"; fi si!
    Copiar

    Observe cómo de nuevo el ; es antes del entonces, 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 o si necesita ser terminado antes de la siguiente acción que es 'entonces' en el ejemplo de la declaración if, y hacer 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 el i variable ($ I)
    ;: Terminar la instrucción ECHO (terminar cada acción)
    hecho: Indica que este es el final de nuestro bucle

  2. Tomemos este mismo ejemplo pero escríbelo de manera diferente:
    $ para i en 1 2 3 4 5; hacer eco $ i; hecho 1 2 3 4 5
    Copiar

    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.

  3. Aumento de la complejidad de nuestro bucle para incluir archivos:
    $ 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
    Copiar

    ¿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 el i variable, un archivo per/para cada bucle el para 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 por 2.TXT etc.) y Cat ese archivo (mostrarlo) y tomar la primera línea de la misma cabeza -n1. Así, 5 veces 1 es salida, ya que esa es la primera línea en los 5 archivos como podemos ver desde el anterior cabeza -n1 a través de todas .archivos txt.

  4. ¿Qué tal uno muy complejo ahora??
     $ 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 ! 
    Copiar

    ¿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 el en 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 hacer cola -n1 archivo.TXT - una taquigrafía que los nuevos desarrolladores de Bash pueden perder fácilmente. En otras palabras, aquí estamos simplemente imprimiendo 1 (la última línea en 1.txt) seguido inmediatamente por 2 para 2.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:

    $ para i en $ (ls *.txt 2>/dev/null); hacer echo -n "$ (cola -n1 $ i)"; hecho 12345 $
    Copiar

    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 el de 1.TXT ! salida) y el cierre del bucle por el hecho.

    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?

  5. Usando un bucle de tiempo para generar una cadena aleatoria:
    $ 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
    Copiar

    Que parece complejo! Analicémoslo paso a paso. Pero primero, veamos cómo se vería esto dentro de un guión de Bash.

  6. Ejemplo de la misma funcionalidad, implementada dentro de un script bash:
    Prueba 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 "
    Copiar
    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 por fecha +%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 el CONTAR variable a 0
    Myrandom = en la línea 7: configure el Mirandom 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 un romper Se da declaración.
    Count = $ [$ count + 1] En la línea 10: aumentar nuestro CONTAR variable por 1
    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. cuando CONTAR es mayor entonces 10 el bucle terminará)
    Myrandom = ".. en la línea 14: vamos a asignar un nuevo valor a Mirandom
    $ 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 el ALEATORIO 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 boques 10 veces como resultado del CONTAR 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 el ALEATORIO La variable devuelve una variable semi-azar (basada en el Aleatorio = .. 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á en 1 etc. Como el primer carácter de la salida siempre es tomado por el SED!

  7. 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 del mientras bucle en la siguiente línea también, de modo que se vuelve innecesario incluso usar el ; allá.

    $ Cat Test2.sh #!/bin/bash para i en $ (seq 1 3) hacer eco "... bucle ... $ yo ..." Hecho
    Copiar
    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.

  8. Finalmente, echemos un vistazo a un bucle Bash 'hasta':
    $ Nr = 0; hasta [$ nr -eq 5]; hacer echo "$ nr"; Nr = $ [$ nr + 1]; hecho 0 1 2 3 4
    Copiar

    Analicemos este ejemplo:

    NR = 0: Aquí establece una variable nombrada Nr, a cero
    hasta: Comenzamos nuestro bucle 'hasta'
    [$ Nr -eq 5]: Este es nuestro si condición o mejor nuestra hasta condición. yo digo si Como la sintaxis (y el trabajo) es similar a la del comando de prueba, yo.mi. el comando de subestimación que se usa en si declaraciones. En bash, el comando de prueba también puede estar representado por un solo ["] soportes. El $ Nr -eq 5 prueba medias; Cuando nuestra variable Nr alcanza las 5, entonces la prueba se volverá verdadera, a su vez haciendo el hasta 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 variable Nr
    Nr = $ [$ nr + 1];: Aumente nuestra variable por uno. El ps El método de cálculo es específico de Bash
    hecho: Terminar nuestra cadena de acción/código de bucle

    Como 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.

  9. 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