Como escrevo um loop for no bash
Pergunta
Estou procurando o loop básico como:
for(int i = 0; i < MAX; i++) {
doSomething(i);
}
mas para festa.
Solução
De esse site:
for i in $(seq 1 10);
do
echo $i
done
Outras dicas
for ((i = 0 ; i < max ; i++ )); do echo "$i"; done
A critica for
consiste em uma variável (o iterador) e uma lista de palavras onde o iterador irá, bem, iterar.
Então, se você tiver uma lista limitada de palavras, basta colocá-las na seguinte sintaxe:
for w in word1 word2 word3
do
doSomething($w)
done
Provavelmente você deseja iterar alguns números, então você pode usar o seq
comando para gerar uma lista de números para você:(de 1 a 100, por exemplo)
seq 1 100
e use-o no loop FOR:
for n in $(seq 1 100)
do
doSomething($n)
done
Note o $(...)
sintaxe.É um comportamento bash, permite passar a saída de um comando (no nosso caso, de seq
) para outro (o for
)
Isso é realmente útil quando você precisa iterar todos os diretórios em algum caminho, por exemplo:
for d in $(find $somepath -type d)
do
doSomething($d)
done
As possibilidades são infinitas para gerar as listas.
Bash 3.0+ pode usar esta sintaxe:
for i in {1..10} ; do ... ; done
..que evita gerar um programa externo para expandir a sequência (como seq 1 10
).
Claro, isso tem o mesmo problema que o for(())
solução, estando vinculado ao bash e até mesmo a uma versão específica (se isso for importante para você).
Tente o bash
ajuda integrada:
$ help for
for: for NAME [in WORDS ... ;] do COMMANDS; done
The `for' loop executes a sequence of commands for each member in a
list of items. If `in WORDS ...;' is not present, then `in "$@"' is
assumed. For each element in WORDS, NAME is set to that element, and
the COMMANDS are executed.
for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done
Equivalent to
(( EXP1 ))
while (( EXP2 )); do
COMMANDS
(( EXP3 ))
done
EXP1, EXP2, and EXP3 are arithmetic expressions. If any expression is
omitted, it behaves as if it evaluates to 1.
Normalmente gosto de usar uma pequena variante do loop for padrão.Costumo usar isso para executar um comando em uma série de hosts remotos.Aproveito a expansão de chaves do bash para criar loops for que me permitem criar loops for não numéricos.
Exemplo:
Quero executar o comando uptime nos hosts frontend 1-5 e nos hosts backend 1-3:
% for host in {frontend{1..5},backend{1..3}}.mycompany.com
do ssh $host "echo -n $host; uptime"
done
Normalmente executo isso como um comando de linha única com ponto e vírgula no final das linhas, em vez da versão mais legível acima.A consideração de uso da chave é que as chaves permitem especificar vários valores a serem inseridos em uma string (por exemplo,pre{foo,bar}post resulta em prefoopost, prebarpost) e permite contagens/sequências usando pontos duplos (você pode usar a..z etc.).No entanto, a sintaxe de ponto duplo é um novo recurso do bash 3.0;versões anteriores não suportarão isso.
#! /bin/bash
function do_something {
echo value=${1}
}
MAX=4
for (( i=0; i<MAX; i++ )) ; {
do_something ${i}
}
Aqui está um exemplo que também pode funcionar em shells mais antigos, embora ainda seja eficiente para grandes contagens:
Z=$(date) awk 'BEGIN { for ( i=0; i<4; i++ ) { print i,"hello",ENVIRON["Z"]; } }'
Mas boa sorte fazendo coisas úteis dentro de awk
: Como faço para usar variáveis de shell em um script awk?
se você estiver interessado apenas em bash o "for(( ...))" apresentada acima é a melhor, mas se você quiser algo compatível com POSIX SH que funcione em todas as unidades, você terá que usar "expr" e "while", e isso porque "(())" ou "seq " ou "i=i+1" não são tão portáteis entre vários shells
Eu uso variações disso o tempo todo para processar arquivos...
para arquivos em *.log;do echo "Faça coisas com:$arquivos";echo "Faça mais coisas com:$arquivos";feito;
Se você está interessado em processar listas de arquivos, consulte o -execdir opção para arquivos.