≡ Menu

HowTo: Iterate Bash For Loop Variable Range Under Unix / Linux

How can I iterate bash for loop using a variable range of numbers in Unix or Linux or BSD or Apple OS X operating systems?

You can use the following syntax for setting up ranges:

 
#!/bin/bash
for i in {1..5}
do
   echo "$i"
done
 

However, the following will not work:

#!/bin/bash
START=1
END=5
for i in {$START..$END}
do
   echo "$i"
done
 

Recommended solution

To fix this problem use three-expression bash for loops syntax which share a common heritage with the C programming language. It is characterized by a three-parameter loop control expression; consisting of an initializer (EXP1), a loop-test or condition (EXP2), and a counting expression (EXP3):

 
#!/bin/bash
START=1
END=5
echo "Countdown"
 
for (( c=$START; c<=$END; c++ ))
 do
 	echo -n "$c "
 	sleep 1
 done
 
 echo
 echo "Boom!"
 

Sample outputs:

Countdown
1 2 3 4 5
Boom!

while...do..done

Another option is to use the bash while statement which is used to execute a list of commands repeatedly:

 
#!/bin/bash
START=1
END=5
## save $START, just in case if we need it later ##
i=$START
while [[ $i -le $END ]]
do
    echo "$i"
    ((i = i + 1))
done
 

Fixing the original code with eval

With eval builtins the arguments are concatenated together into a single command, which is then read and executed:

 
#!/bin/bash
START=1
END=5
for i in $(eval echo "{$START..$END}")
do
	echo "$i"
done
 

A note about iterate through an array

The Bash shell support one-dimensional array variables and you can use the following syntax to iterate through an array:

 
#!/bin/bash
 
## define an array ##
arrayname=( Dell HP Oracle )
 
## get item count using ${arrayname[@]} ##
for m in "${arrayname[@]}"
do
  echo "${m}"
  # do something on $m #
done
 

Sample outputs:

Dell
HP
Oracle
Tweet itFacebook itGoogle+ itPDF itFound an error/typo on this page?

{ 4 comments… add one }

  • xeuler May 4, 2012, 3:06 am

    Hi.

    when i use {1..10000000} in

    for x in {1..10000000} ; do : ; done
    * do nothing

    bash uses 2 GB of ram.

    Is the same when i use seq

    for i in $(seq 1 10000000); do :; done

    The memory is still in use until i close de session (terminal).

    it’s like fork bom xp

  • Mark S May 15, 2012, 6:04 pm

    When working with contiguous numerical ranges that increase, I find the command ‘seq’ to be more efficient and powerful. For example, let’s go from 0 to 20 by increments of 3 and output some fibonacci stylings :-)

    for i in `seq 0 3 20`
    do
    ((j = $j + $i))
    echo $j
    done
    

    ‘seq’ also has a few options such as padding with leading zeros, changing the field separator and changing the printf format. The -w for leading zeros comes in handy frequently. Issue ‘man seq’ for the details.

  • Xiaofeng July 12, 2012, 2:26 am

    hi VIVEK, could u tell me why your second sample didn’t work? it’s unusual to my intuition. and not easy to understand.

  • Jason September 26, 2012, 2:21 am

    There is incorrect information in the last example. It says:

    ## get item count using ${arrayname[@]} ##

    This only concatenates the items of the array together separated by whitespace (which works for the example). But to get the count of an array,

    ${#arrayname[@]}

    or

    ${#arrayname[*]}

    is used.

Leave a Comment