viernes, 16 de junio de 2017

for: Forma tradicional del shell

La sintaxis original del comando for es:

for variable [in palabras]; do
    comandos
done

Donde variable es el nombre de la variable que se incrementará durante la ejecución del bucle, palabras es una lista opcional de elementos que se asignarán secuencialmente a variable, y comandos son los comandos que se van a ejecutar en cada iteración del bucle.

El comando for es útil en la línea de comandos. Podemos comprobar fácilmente cómo funciona:

[me@linuxbox ~]$ for i in A B C D; do echo $i; done
A
B
C
D

En este ejemplo, se le da a for una lista de cuatro palabras: "A", "B", "C" y "D". Con una lista de cuatro palabras, el bucle se ejecuta cuatro veces. Cada vez que se ejecuta el bucle, se asigna una palabra a la variable i, Dentro del bucle, tenemos un comando echo que muestra el valor de i para mostrar la asignación. Al igual que los bucles while y until, la palabra done cierra el bucle.

La característica realmente potente de for es el número de formas interesantes de crear la lista de palabras. Por ejemplo, a través de expansión con llaves:

[me@linuxbox ~]$ for i in {A..D}; do echo $i; done
A
B
C
D

or expansión de rutas:

[me@linuxbox ~]$ for i in distros*.txt; do echo $i; done
distros-by-date.txt
distros-dates.txt
distros-key-names.txt
distros-key-vernums.txt
distros-names.txt
distros.txt
distros-vernums.txt
distros-versions.txt

o sustitución de comandos:

#!/bin/bash

# longest-word : find longest string in a file

while [[ -n $1 ]]; do
    if [[ -r $1 ]]; then
        max_word=
        max_len=0
        for i in $(strings $1); do
            len=$(echo $i | wc -c)
            if (( len > max_len )); then
                max_len=$len
                max_word=$i
            fi
        done
        echo "$1: '$max_word' ($max_len characters)"
    fi
    shift
done

En este ejemplo, buscamos la cadena más larga dentro de una archivo. Una vez que le damos uno o más nombres de archivo en la línea de comandos, este programa usa el programa strings (que está incluido en el paquete GNU binutils) para generar una lista de "words" en texto legible en cada archivo. El bucle for procesa, de una en una, cada palabra y determina si la palabra actual es la más larga encontrada hasta el momento. Cuando concluye el bucle, se muestra la palabra más larga.

Si la parte opcional in words del comando for se omite, for procesa por defecto los parámetros posicionales. Modificaremos nuestro script longest-word para usar este método:

#!/bin/bash

# longest-word2 : find longest string in a file

for i; do
    if [[ -r $i ]]; then
        max_word=
        max_len=0
        for j in $(strings $i); do
            len=$(echo $j | wc -c)
            if (( len > max_len )); then
                max_len=$len
                max_word=$j
            fi
        done
        echo "$i: '$max_word' ($max_len characters)"
    fi
done

Como podemos ver, hemos cambiado el bucle más externo para usar for en lugar de while. Al omitir la lista de palabras en el comando for, se usan los parámetros posicionales en su lugar. Dentro del bucle, las instancias previas de la variable i han sido cambiadas a la variable j. El uso de shift también ha sido eliminado.

No hay comentarios:

Publicar un comentario