Um comando de iteração, ou laço, permite que um conjunto de instruções seja executado repetidamente até que ocorra uma certa condição. No Linux o interpretador de comandos Bash, da mesma forma que às principais linguagens de programação, também possui os comandos básicos de iteração e são os comandos for, while e until.
O comando for é o mais simples dos três, utiliza um contador com um início e fim pré-definido e o incremento do passo. Durante cada passo a variável "argumento" recebe o valor de cada membro da "lista". O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:
Como vamos executar todo o comando em uma única linha no prompt do shell, então é necessário alguns ponto-e-vírgulas:
Veja alguns exemplos de lista para compor um contador para a repetição. Nos casos abaixo todos produzem o mesmo efeito, contando de 1 à 10. Em dois exemplos foi usado o utilitário seq, que imprime uma sequência de números:
A lista de valores pode conter palavras ao invés de números, veja estes exemplos. O segundo exemplo utiliza um arquivo que contém as palavras:
O incremento do passo pode ser mais de 1 em 1. Os exemplos abaixo produzem o mesmo efeito, contando de 1 à 16 com passo 2:
É possível também utilizar duas variáveis no contador, na sintaxe semelhante à linguagem C:
Exemplos práticos com o uso do comando for:
O comando while testa por uma condição no início do laço e mantém a iteração enquanto esta condição é verdadeira (retorna 0 quando falso). Diferentemente do comando for, o comando while é usado quando o número de repetições não é conhecido de antemão. O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:
Mais uma vez, como vamos executar todo o comando em uma única linha, no prompt do shell, então é necessário alguns ponto-e-vírgulas:
Para o comando while executar o laço a condição já deve existir. Veja este exemplo onde é inicializada a variável de controle antes do comando while (Obs.: é necessário os espaços dentro dos colchetes pois é um teste de condição):
Ou, produzindo o mesmo resultado:
Uma outra forma, por exemplo, é suprir a entrada com o conteúdo de um arquivo:
Ou, produzindo o mesmo resultado:
Exemplos práticos com o uso do comando while:
O comando until testa por uma condição no início do laço e mantém esta iteração enquanto a condição for falsa (diferentemente do comando similar em outras linguagens), sendo o oposto do comando while. Também o comando until é usado quando o número de repetições não é conhecido de antemão. O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:
Como sempre, vamos executar todo o comando em uma única linha, no prompt do shell, então é necessário alguns ponto-e-vírgulas:
Também como o comando while, para o until executar o laço a condição já deve existir. Neste exemplo é inicializada a variável de controle antes do comando until:
Ou, produzindo o mesmo resultado:
Da mesma forma que demonstrado no comando while, também é possível suprir a entrada com o conteúdo de um arquivo.
Exemplos práticos com o uso do until:
Nestes três comandos de iteração é possível interromper o comando ou somente pular o passo atual e continuar no próximo. Para isso usa-se respectivamente os comandos break e continue na posição desejada entre o do e o done. Obviamente para ter este controle certamente vai ser necessário o uso de um comando condicional, como o if.
Como escolher entre os laços for, while ou until? Pode ser possível conseguir o mesmo efeito com os três comandos de laço. Veja os comandos abaixo, todos produzem o mesmo resultado, então provavelmente o melhor será aquele que visualmente for mais fácil de entender o algoritmo. Mas observe que o comando for é mais utilizado quando o número de iterações é conhecido e os comandos while e until servem para um número impreciso de iterações:
O comando for é o mais simples dos três, utiliza um contador com um início e fim pré-definido e o incremento do passo. Durante cada passo a variável "argumento" recebe o valor de cada membro da "lista". O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:
for argumento in lista
do
comando(s)
done
Como vamos executar todo o comando em uma única linha no prompt do shell, então é necessário alguns ponto-e-vírgulas:
for argumento in lista; do comando(s); done
Veja alguns exemplos de lista para compor um contador para a repetição. Nos casos abaixo todos produzem o mesmo efeito, contando de 1 à 10. Em dois exemplos foi usado o utilitário seq, que imprime uma sequência de números:
for i in 1 2 3 4 5 6 7 8 9 10; do echo -n "$i "; done
for i in $(seq 10); do echo -n "$i "; done
for i in `seq 10`; do echo -n "$i "; done
for i in {1..10}; do echo -n "$i "; done
for ((i=1; i<=10; i++)); do echo -n "$i "; done
A lista de valores pode conter palavras ao invés de números, veja estes exemplos. O segundo exemplo utiliza um arquivo que contém as palavras:
for dia in Segunda Terça Quarta Quinta Sexta; do echo $dia; done
for dia in `cat semana.txt`; do echo $dia; done
O incremento do passo pode ser mais de 1 em 1. Os exemplos abaixo produzem o mesmo efeito, contando de 1 à 16 com passo 2:
for ((i=1;i<=16;i+=2)); do echo $i; done
for i in $(seq 1 2 16); do echo $i; done
for i in `seq 1 2 16`; do echo $i; done
for i in 1 3 5 7 9 11 13 15; do echo $i; done
foi i in {1..16..2}; do echo $i; done # A partir do bash versão 4.
É possível também utilizar duas variáveis no contador, na sintaxe semelhante à linguagem C:
for ((i=1, j=1; i<=10; i++, j++)); do echo -n "$i-$j "; done
Exemplos práticos com o uso do comando for:
for i in *.*; do novo="$(echo "$i" | sed 'y/ÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÇÑàáâãäåèéêëìíîïòóôõöùúûüçñ/
AAAAAAEEEEIIIIOOOOOUUUUCNaaaaaaeeeeiiiiooooouuuucn/')"; mv "$i" "$novo"; done
for i in `ls *-6_*.pdf`; do mv $i ${i/-6_/-06_}; done
n=1; for nome in $(awk 'BEGIN{FS=":"}{print $1}' < /etc/passwd ); do echo "USUARIO #$n = $nome";
let n+=1; done
for file in *.mp3; do mkdir -p "$(mp3info -p "%a/%l" "$file")" && mv "$file" "$(mp3info -p
"%a/%l/%t.mp3" "$file")"; done
for x in $(lynx -dump http://marx.vanderlinden.com.br/sem/2009.1/fi.php | awk '{print $2}' | grep
.pdf); do wget -c $x; done
for arquivo in $( find /usr/local/bin/ -type f -name '*' | sort ); do strings -f $arquivo | grep
"GPL" | sed -e "s%/usr/local/bin/%%"; done
O comando while testa por uma condição no início do laço e mantém a iteração enquanto esta condição é verdadeira (retorna 0 quando falso). Diferentemente do comando for, o comando while é usado quando o número de repetições não é conhecido de antemão. O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:
while condição
do
comando(s)
done
Mais uma vez, como vamos executar todo o comando em uma única linha, no prompt do shell, então é necessário alguns ponto-e-vírgulas:
while condição; do comando(s); done
Para o comando while executar o laço a condição já deve existir. Veja este exemplo onde é inicializada a variável de controle antes do comando while (Obs.: é necessário os espaços dentro dos colchetes pois é um teste de condição):
i=1; while [ $i -le 10 ]; do echo -n "$i "; let i+=1; done
Ou, produzindo o mesmo resultado:
i=1; while ((i<=10)); do echo $i; ((i+=1)); done
Uma outra forma, por exemplo, é suprir a entrada com o conteúdo de um arquivo:
cat semana.txt | while read linha; do echo -n "$linha "; done
Ou, produzindo o mesmo resultado:
while read linha; do echo -n "$linha "; done < <(cat semana.txt)
Exemplos práticos com o uso do comando while:
find /usr/share/ -regextype posix-egrep -iregex '.*\.(jpg|jpeg|gif|png|tif|tiff|bmp|svg)' -type f
-print | while read IMAGEM; do convert -thumbnail 120x120 -compress JPEG -quality 20 -delete 1--1
"$IMAGEM" thumbs/"$(echo "${IMAGEM}" | sed 's/.*\///g')".jpg; done
while read nome; do echo "USER #$n = $nome"; let n+=1; done < <(awk 'BEGIN{FS=":"}{print $1}'
< /etc/passwd )
seq 1 100 | while read i; do echo -n "texto${i}.txt "; touch texto${i}.txt 2>&1; done
while read i; do echo -n "texto${i}.txt "; touch texto${i}.txt 2>&1; done < <(seq 1 100)
while read arquivo; do strings -f $arquivo | grep "GPL" | sed -e "s%/usr/local/bin/%%";
done < <( find /usr/local/bin/ -type f -name '*' | sort )
O comando until testa por uma condição no início do laço e mantém esta iteração enquanto a condição for falsa (diferentemente do comando similar em outras linguagens), sendo o oposto do comando while. Também o comando until é usado quando o número de repetições não é conhecido de antemão. O conjunto de instruções que será executado repetidamente deve ficar entre as palavras reservadas do e done. Sua sintaxe básica é apresentada abaixo:
until condição
do
comando(s)
done
Como sempre, vamos executar todo o comando em uma única linha, no prompt do shell, então é necessário alguns ponto-e-vírgulas:
until condição; do comando(s); done
Também como o comando while, para o until executar o laço a condição já deve existir. Neste exemplo é inicializada a variável de controle antes do comando until:
i=1; until [ $i -gt 10 ]; do echo $i; let i+=1; done
Ou, produzindo o mesmo resultado:
i=1; until ((i>10)); do echo $i; ((i+=1)); done
Da mesma forma que demonstrado no comando while, também é possível suprir a entrada com o conteúdo de um arquivo.
Exemplos práticos com o uso do until:
until [ -e teste.txt ]; do echo -e "Crie o arquivo teste.txt\n"; sleep 5; done
until [ $(ls -l eventos.log | awk '{print $5}') -gt 5000 ]; do echo "Arquivo log ainda pequeno";
sleep 1; done
Nestes três comandos de iteração é possível interromper o comando ou somente pular o passo atual e continuar no próximo. Para isso usa-se respectivamente os comandos break e continue na posição desejada entre o do e o done. Obviamente para ter este controle certamente vai ser necessário o uso de um comando condicional, como o if.
Como escolher entre os laços for, while ou until? Pode ser possível conseguir o mesmo efeito com os três comandos de laço. Veja os comandos abaixo, todos produzem o mesmo resultado, então provavelmente o melhor será aquele que visualmente for mais fácil de entender o algoritmo. Mas observe que o comando for é mais utilizado quando o número de iterações é conhecido e os comandos while e until servem para um número impreciso de iterações:
for ((i=1; i<=10; i++)); do echo "$i "; done
i=1; while ((i<=10)); do echo $i; ((i+=1)); done
i=1; until ((i>10)); do echo $i; ((i+=1)); done
Nenhum comentário:
Postar um comentário