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

by on April 20, 2012 · 4 comments· LAST UPDATED April 20, 2012

in

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
TwitterFacebookGoogle+PDF versionFound an error/typo on this page? Help us!

{ 4 comments… read them below or add one }

1 xeuler May 4, 2012 at 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

Reply

2 Mark S May 15, 2012 at 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.

Reply

3 Xiaofeng July 12, 2012 at 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.

Reply

4 Jason September 26, 2012 at 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.

Reply

Leave a Comment

Tagged as: , , , , , , , , , , , , , ,

Previous Faq:

Next Faq: