web-dev-qa-db-fra.com

Script shell "pour" syntaxe de boucle

J'ai le travail suivant:

for i in {2..10}
do
    echo "output: $i"
done

Il produit un tas de lignes de output: 2, output: 3, etc.

Cependant, essayez d’exécuter ce qui suit:

max=10
for i in {2..$max}
do
    echo "$i"
done

produit ce qui suit:

output: {2..10}

Comment faire en sorte que le compilateur réalise qu'il doit traiter $ max comme l'autre extrémité du tableau et non comme une chaîne?

178
eykanal

Le développement d'accolade, {x..y} est effectué avant les autres extensions, vous ne pouvez donc pas l'utiliser pour des séquences de longueur variable.

Au lieu de cela, utilisez la méthode seq 2 $max comme tilisateur mob déclaré .

Donc, pour votre exemple, ce serait:

max=10
for i in `seq 2 $max`
do
    echo "$i"
done
219
whatsisname

Essayez la version à expression arithmétique de for:

max=10
for (( i=2; i <= $max; ++i ))
do
    echo "$i"
done

Ceci est disponible dans la plupart des versions de bash, et devrait également être compatible avec Bourne Shell (sh).

67
system PAUSE

Montez la boucle manuellement:

 i = 0 
 max = 10 
 tandis que [$ i -lt $ max] 
 font 
 écho "sortie: $ i" 
 true $ ((i ++)) 
 terminé 

Si vous ne devez pas être totalement POSIX, vous pouvez utiliser la boucle arithmétique pour:

 max = 10 
 pour ((i = 0; i <max; i ++)); echo "output: $ i"; terminé

Ou utilisez note (1) sur les systèmes BSD:

 pour i en $ (jot 0 10); echo "output: $ i"; terminé
27
Nietzche-jou

Si la commande seq disponible sur votre système:

for i in `seq 2 $max`
do
  echo "output: $i"
done

Sinon, utilisez le seq du pauvre homme avec Perl:

seq=`Perl -e "\$,=' ';print 2..$max"`
for i in $seq
do
  echo "output: $i"
done

Regardez ces guillemets.

9
mob

Il y a plus d'une façon de le faire.

max=10
for i in `eval "echo {2..$max}"`
do
    echo "$i"
done
9
ephemient

C'est un moyen:
Frapper:

max=10
for i in $(bash -c "echo {2..${max}}"); do echo $i; done

La méthode Bash ci-dessus fonctionnera également pour ksh et zsh, lorsque bash -c sera remplacé par ksh -c ou zsh -c, respectivement.

Remarque: for i in {2..${max}}; do echo $i; done fonctionne dans zsh et ksh.

4
Jahid

On peut itérer en boucle comme en C.

#!/bin/bash
for ((i=1; i<=20; i=i+1))
do 
      echo $i
done
4
rashedcs

Ici, cela fonctionnait sous Mac OS X.

Il inclut l'exemple d'une date BSD, comment incrémenter et décrémenter la date également:

for ((i=28; i>=6 ; i--));
do
    dat=`date -v-${i}d -j "+%Y%m%d"` 
    echo $dat
done
2
minhas23

Comme je n'avais pas installé la commande seq sur mon système (Mac OS X v10.6.1 (Snow Leopard)), j'ai fini par utiliser une boucle while:

max=5
i=1

while [ $max -gt $i ]
do
    (stuff)
done

* hausse des épaules * Tout ce qui fonctionne.

2
eykanal

Celles-ci font toutes {1..8} et devraient toutes être POSIX. Ils ne seront pas non plus cassés si vous mettez un continue conditionnel dans la boucle. La manière canonique:

f=
while [ $((f+=1)) -le 8 ]
do
  echo $f
done

Autrement:

g=
while
  g=${g}1
  [ ${#g} -le 8 ]
do
  echo ${#g}
done

et un autre:

set --
while
  set $* .
  [ ${#} -le 8 ]
do
  echo ${#}
done
1
user4427511

Utilisation:

max=10
for i in `eval echo {2..$max}`
do
    echo $i
done

Vous avez besoin de l'appel explicite 'eval' pour réévaluer le {} après la substitution de variable.

1
Chris Dodd