Publi

Bucles for en BASH

loooop

No por ser un lenguaje de script enfocado a la línea de comando vamos a dejar de poder hacer un bucle. Es más, si los archivos batch pueden, estos scripts no van a ser menos. Es común ver un bucle for en bash de este modo:

1
2
3
4
for i in $lista;
do
   echo $i;
done

Donde lista puede ser:

lista=”Una serie de cosas separadas por un espacio normalmente. Es un carácter del $IFS

El IFS es el Internal Field Separator (Separador Interno de Campo) y se usa para saber cuándo parar un read; por defecto se usa el espacio/tabulador/nueva línea. En nuestro caso será el separador de los objetos de la lista.

Por ejemplo con este bucle for podemos listar las posibles frecuencias de nuestro procesador (sólo si es compatible con cpufreq y tenemos el módulo del kernel cargado):

1
2
3
4
for j in `cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies`
do
echo "Frecuencia: "$j" Hz"
done

Es decir, hacemos que nuestra lista sea el resultado de la ejecución de “cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies

Este método se parece mucho al for each que tienen muchos lenguajes.

Pero, ¿ qué tal el bucle for de toda la vida? ¿ Ése en el que contábamos de un número hasta otro número ? Podemos hacerlo de dos formas:

for i in ….

1
2
3
4
for i in `seq 4 90`
do
   echo $i
done

Donde en seq podemos colocar el número de inicio y el de fin, uno detrás de otro, si ejecutamos seq en el terminal generará una salida con un número en cada línea (aunque se puede cambiar con -s). Aunque también podremos modificar el incremento (2, 3, 4…). Por ejemplo:

$ seq 1 10 1000

que contará de 1 a 1000 de 10 en 10: 1..11..21..31…….991 (hasta 1000 no puede llegar porque se pasa)
Si queremos contar hacia atrás debemos especificar este incremento negativo:

$ seq 10 -1 0

que contará de 10 a 0: 10..9..8..7…….0

El método tradicional

1
2
3
4
for (( i=0; i<1000; i++ ))
do
   echo $i
done

¡ Anda ! Igual que en C, pero con dos paréntesis… además, éste método lo podemos extender un poco más. Lo mismo que podemos hacer:

for (( i=0; i<1000; i=i+5 ))

Para contar de 5 en 5

for ((i=1000; i>0; i=i-5))

Para contar de -5 en -5

podemos hacer lo siguiente:

for (( i=1000; i>0; i=`expr $i / 2`))

Para ir dividiendo el número entre dos, o:

for (( i=1; i<100; i=`expr $i \* 2`))

para ir multiplicando por dos

En definitiva, cualquier operación que podamos hacer desde la línea de comando, por ejemplo con expr, aunque si se nos queda corto siempre podemos usar bc (haré un algún post sobre bc).

Con expr podemos hacer algunas operaciones matemáticas simples (suma, resta, multiplicación, división, resto, and y or) con los siguientes símbolos respectivamente (+, -, *, /, %, &, |), aunque *, & y | deben ser escapados con una \ (contra barra).
Cada elemento en la expresión debe ir con un espacio, dejo como ejemplo las siguientes expresiones:

$ expr 100 \& 0
0
$ expr 100 \& 1
100
$ expr 0 \& 3
0
$ expr 0 \| 3
3
$ expr 23 \* 45 + 20 – 4 % 3
1054
$ expr 3 % 2
1
$ a=3
$ expr $a + 1
4

Es cierto que expr hace muchas más cosas: podemos poner paréntesis para dar preferencia a algunas operaciones, y hay palabras clave para operar con cadenas de caracteres.

Actualización 20/12/2015: He arreglado algunos símbolos “menor que” que no se veían bien.

Foto: Spookuygonk (Flickr)

También podría interesarte...

There are 11 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. nelson /
    Usando Google Chrome Google Chrome 6.0.428.0 en Linux Linux

    muchas gracias , me sirvio bastante, no estoy recien empezando a ocupar el ciclo “for”, y no entiendo aun mucho su uso, pero me sirvio para entenderlo mas, saludos, bendiciones

  3. Gaspar Fernández / Post Author
    Usando Mozilla Firefox Mozilla Firefox 5.0 en Linux Linux

    @nelson
    Saludos Nelson! Muchas gracias por tu comentario.

  4. Christopher /
    Usando Mozilla Firefox Mozilla Firefox 51.0 en Ubuntu Linux Ubuntu Linux

    Gracias

    1. Gaspar Fernández /
      Usando Mozilla Firefox Mozilla Firefox 51.0 en Ubuntu Linux Ubuntu Linux

      ¡ Gracias a ti !

  5. Jimmy Olano /
    Usando Mozilla Firefox Mozilla Firefox 51.0 en Ubuntu Linux Ubuntu Linux

    Ya hicimos un enlace hacia vuestro artículo en nuestro tutorial sobre BASH, ¡gracias por compartir!

    1. Gaspar Fernández /
      Usando Mozilla Firefox Mozilla Firefox 51.0 en Ubuntu Linux Ubuntu Linux

      Pásame el link del tutorial ! Seguro que está muy interesante 🙂

  6. Pingback: GNU/Linux: linea de comandos (shell). – KS7000+WP /

  7. ElTioDeLaTecla /
    Usando Mozilla Firefox Mozilla Firefox 51.0 en Ubuntu Linux Ubuntu Linux

    Sabrás mucho de BASH, pero de matemáticas …
    Ningún número se multiplica “entre” otro, se multiplica POR otro.

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 51.0 en Ubuntu Linux Ubuntu Linux

      Qué duro eres! Para un lapsus copypastero que tiene uno… 🙂 Muchas gracias por el aviso.

  8. jose del montes /
    Usando Mozilla Firefox Mozilla Firefox 53.0 en Windows Windows NT

    Hola, gracias por la informacion. Soy nuevo en linux y he estado tratando de lograr trabajar este script que en windows me funciona de lo mas bien

    for /f “tokens=*” %%a in (info.txt) do (
    echo = PROCESANDO: %%a
    sequencia %%a
    echo = DONE =
    )

    Lo que hace es copiar informacion de info.txt y remplanzarlo en donde tenga esta variable %1 dentro del documento llamado sequencia que a su ves es otro archivo .bat , no se si me explico bien. Si alguien me pudiera ayudar se lo agradeceria mucho.

Leave a Reply