se tivermos uma variável como ArrayLength=${#array[@]}como usamos aqui em vez de max?
Kasun Siyambalapitiya
34
O bash forconsiste em uma variável (o iterador) e uma lista de palavras onde o iterador irá, bem, iterar.
Portanto, se você tiver uma lista limitada de palavras, basta colocá-las na seguinte sintaxe:
for w in word1 word2 word3do
doSomething($w)done
Provavelmente você deseja iterar ao longo de alguns números, então você pode usar o seqcomando para gerar uma lista de números para você: (de 1 a 100, por exemplo)
seq 1100
e usá-lo no loop FOR:
for n in $(seq 1100)do
doSomething($n)done
Observe a $(...)sintaxe. É um comportamento bash, permite que você passe a saída de um comando (no nosso caso de seq) para outro (o for)
Isso é muito útil quando você precisa iterar sobre 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.
Boa resposta, mas você pode querer incluir o for ((i = 0; i <MAX; i ++)); faça doSomething ($ i); variante feita também. Eu acho que geralmente é preferível a variante for i in $ (seq 0 MAX), pois a última irá primeiro gerar todos os números de 0 a MAX antes de realmente executar o loop.
mweerden,
30
O 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 da for(())solução, estar vinculado ao bash e até mesmo a uma versão específica (se isso for importante para você).
$ help forfor:for NAME [in WORDS ...;]do COMMANDS;doneThe`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;doneEquivalent 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.
Eu não percebi isso antes, mas uma sintaxe semelhante é mostrada em uma das respostas anteriores. A única coisa aqui é o uso de chaves em vez do par típico do/ done.
Brent Bradburn
4
Normalmente gosto de usar uma ligeira variante no padrão para loop. Costumo usar isso para executar um comando em uma série de hosts remotos. Aproveito a expansão da chave do bash para criar loops for que me permitem criar loops for não numéricos.
Exemplo:
Quero executar o comando uptime nos hosts de front-end 1-5 e nos hosts de back-end 1-3:
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 principal consideração de uso é que os colchetes permitem que você especifique vários valores a serem inseridos em uma string (por exemplo, pré {foo, bar} resultados de pós em prefoopost, pré-barra) e permite a contagem / sequências usando os pontos duplos (você pode usar um. .z etc.). No entanto, a sintaxe de período duplo é um novo recurso do bash 3.0; versões anteriores não suportam isso.
Relacionado a isso, e se $ host var for uma linha vazia por algum acidente? Ainda iria disparar ssh. Então, como faço para evitar isso? No meu caso estou fazendo algo diferente e sua resposta vai me ajudar. Estou tentando verificar se há novas mensagens no Gmail e, se forem encontradas, envio um SMS de de e assunto. Minha pergunta se chama "Conectando dois comandos Bash" se você quiser lê-la.
Volomike
Não acredito que você receba um $ host var vazio. Isso ocorre porque o exemplo acima está usando a expansão de chaves. O loop for define explicitamente a variável $ host para os valores: frontend1.mycompany.com frontend2.mycompany.com. . backend1.mycompany.com Mas se você vir uma maneira de ter um valor nulo; Eu estaria interessado em saber. Você poderia executar o ssh dentro de um teste condicional se fosse uma preocupação.
terson
1
se você está interessado apenas em bash a solução "for ((...))" apresentada acima é a melhor, mas se você quiser algo compatível com POSIX SH que funcione em todos os unices 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
Respostas:
Deste site :
fonte
fonte
ArrayLength=${#array[@]}
como usamos aqui em vez demax
?O bash
for
consiste em uma variável (o iterador) e uma lista de palavras onde o iterador irá, bem, iterar.Portanto, se você tiver uma lista limitada de palavras, basta colocá-las na seguinte sintaxe:
Provavelmente você deseja iterar ao longo de 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)e usá-lo no loop FOR:
Observe a
$(...)
sintaxe. É um comportamento bash, permite que você passe a saída de um comando (no nosso caso deseq
) para outro (ofor
)Isso é muito útil quando você precisa iterar sobre todos os diretórios em algum caminho, por exemplo:
As possibilidades são infinitas para gerar as listas.
fonte
O Bash 3.0+ pode usar esta sintaxe:
..que evita gerar um programa externo para expandir a sequência (como
seq 1 10
).Claro, isso tem o mesmo problema da
for(())
solução, estar vinculado ao bash e até mesmo a uma versão específica (se isso for importante para você).fonte
Experimente a
bash
ajuda integrada:fonte
Aqui está um exemplo que também pode funcionar em shells mais antigos, embora seja eficiente para grandes contagens:
Mas boa sorte fazendo coisas úteis dentro de
awk
: Como faço para usar variáveis de shell em um script awk?fonte
do
/done
.Normalmente gosto de usar uma ligeira variante no padrão para loop. Costumo usar isso para executar um comando em uma série de hosts remotos. Aproveito a expansão da chave do bash para criar loops for que me permitem criar loops for não numéricos.
Exemplo:
Quero executar o comando uptime nos hosts de front-end 1-5 e nos hosts de back-end 1-3:
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 principal consideração de uso é que os colchetes permitem que você especifique vários valores a serem inseridos em uma string (por exemplo, pré {foo, bar} resultados de pós em prefoopost, pré-barra) e permite a contagem / sequências usando os pontos duplos (você pode usar um. .z etc.). No entanto, a sintaxe de período duplo é um novo recurso do bash 3.0; versões anteriores não suportam isso.
fonte
se você está interessado apenas em bash a solução "for ((...))" apresentada acima é a melhor, mas se você quiser algo compatível com POSIX SH que funcione em todos os unices 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
fonte
Eu uso variações disso o tempo todo para processar arquivos ...
Se você estiver interessado em processar listas de arquivos, procure a opção -execdir para arquivos .
fonte