Reputation: 27017
I have gotten the following to work:
for i in {2..10}
do
echo "output: $i"
done
It produces a bunch of lines of output: 2
, output: 3
, so on.
However, trying to run the following:
max=10
for i in {2..$max}
do
echo "$i"
done
produces the following:
output: {2..10}
How can I get the compiler to realize it should treat $max as the other end of the array, and not part of a string?
Upvotes: 270
Views: 1185553
Reputation: 3725
We can iterate loop like as C programming.
#!/bin/bash
for ((i=1; i<=20; i=i+1))
do
echo $i
done
Upvotes: 19
Reputation: 118595
If the seq
command available on your system:
for i in `seq 2 $max`
do
echo "output: $i"
done
If not, then use poor man's seq
with perl
:
seq=`perl -e "\$,=' ';print 2..$max"`
for i in $seq
do
echo "output: $i"
done
Watch those quote marks.
Upvotes: 19
Reputation: 6140
Brace expansion, {x..y} is performed before other expansions, so you cannot use that for variable length sequences.
Instead, use the seq 2 $max
method as user mob stated.
So, for your example it would be:
max=10
for i in `seq 2 $max`
do
echo "$i"
done
Upvotes: 320
Reputation: 27017
Well, as I didn't have the seq
command installed on my system (Mac OS X v10.6.1 (Snow Leopard)), I ended up using a while
loop instead:
max=5
i=1
while [ $max -gt $i ]
do
(stuff)
done
*Shrugs* Whatever works.
Upvotes: 3
Reputation: 9671
Here it worked on Mac OS X.
It includes the example of a BSD date, how to increment and decrement the date also:
for ((i=28; i>=6 ; i--));
do
dat=`date -v-${i}d -j "+%Y%m%d"`
echo $dat
done
Upvotes: 2
Reputation: 2960
Use:
max=10
for i in `eval echo {2..$max}`
do
echo $i
done
You need the explicit 'eval' call to reevaluate the {} after variable substitution.
Upvotes: 1
Reputation:
These all do {1..8}
and should all be POSIX. They also will not break if you
put a conditional continue
in the loop. The canonical way:
f=
while [ $((f+=1)) -le 8 ]
do
echo $f
done
Another way:
g=
while
g=${g}1
[ ${#g} -le 8 ]
do
echo ${#g}
done
and another:
set --
while
set $* .
[ ${#} -le 8 ]
do
echo ${#}
done
Upvotes: 2
Reputation: 22428
This is a way:
Bash:
max=10
for i in $(bash -c "echo {2..${max}}"); do echo $i; done
The above Bash way will work for ksh
and zsh
too, when bash -c
is replaced with ksh -c
or zsh -c
respectively.
Note: for i in {2..${max}}; do echo $i; done
works in zsh
and ksh
.
Upvotes: 5
Reputation: 38500
Try the arithmetic-expression version of for
:
max=10
for (( i=2; i <= $max; ++i ))
do
echo "$i"
done
This is available in most versions of bash, and should be Bourne shell (sh) compatible also.
Upvotes: 101
Reputation: 14720
Step the loop manually:
i=0 max=10 while [ $i -lt $max ] do echo "output: $i" true $(( i++ )) done
If you don’t have to be totally POSIX, you can use the arithmetic for loop:
max=10 for (( i=0; i < max; i++ )); do echo "output: $i"; done
Or use jot(1) on BSD systems:
for i in $( jot 0 10 ); do echo "output: $i"; done
Upvotes: 40
Reputation: 204678
There's more than one way to do it.
max=10
for i in `eval "echo {2..$max}"`
do
echo "$i"
done
Upvotes: 9