Shell Scripting: Generate or Print Range of Numbers ( Sequence of Numbers for Loop )

Posted on in Categories FreeBSD, Gentoo Linux, Howto, Linux, php, programming, Shell scripting, Tips, Troubleshooting, Ubuntu Linux, UNIX last updated September 26, 2006

One our reader asks:

How do I generate a range of numbers under BASH for loop command? For example, I need to run particular command inside loop 100 or 500 times. Basically I want function that counts FROM and TO a range of numbers like 50-10.

To print a sequence of numbers use GNU seq command. In olden days we use our own shell script. But no more dirty shell script, just use good seq command.

This is quite handy when you want to writing shell scripts that requires loop-using range of numbers.

seq command syntax

seq LAST
seq FIRST LAST
seq FIRST INCREMENT LAST

If FIRST or INCREMENT is omitted, it defaults to 1. That is, an omitted INCREMENT defaults to 1 even when LAST is smaller than FIRST. FIRST, INCREMENT, and LAST are interpreted as floating point values. INCREMENT is usually positive if FIRST is smaller than LAST, and INCREMENT is usually negative if FIRST is greater than LAST.

Try out following examples:
$ seq 5
Output:

1
2
3
4
5

Few more examples:$ seq 5 10
$ seq 0 2 10
$ seq 5 -1 1

seq command and shell script (for loop)

You can use seq command in bash for loop as follows:

#!/bin/bash
for i in $(seq 5)
do
  echo "Welcome $i times"
done

Bash for loop to generate a sequence of numbers

You can also use bash for loop as follows:

#!/bin/bash
for ((a=1; a <= 5 ; a++))
do
   echo "Welcome $a times."
done

Real World Experience

#!/bin/bash
# Script to move topics from old shared hosting to new lighttpd vps server
#
U="http://forum.cyberciti.biz/viewtopic.php?t="
rdu=""
for n in $(seq 1 521)
do
  rdu="$(lynx --dump $U$n | egrep "vt([0-9]+)\.html$" | awk '{ print $2}' | uniq)"
  if [ "$rdu" == "" ]; then
    :
  else
    echo "$n => \"$rdu\","
  fi
  rdu=""
done

Above script generates a new php code (array) to match with variable t so that we can send 301 redirect. So anyone visiting old forum url http://www.cyberciti.biz/nixcraft/forum/viewtopic.php?t=513 will be redirected to new url 😀
Next, I just need to copy and paste the array generated by shell script into viewtopic.php and all users are redirected to new url with 301 http code.

<?php
$URLS = array (
....
..
3 => "http://forum.cyberciti.biz/mysql-cluster-vt3.html",
4 => "http://forum.cyberciti.biz/nice-look-and-feel-vt4.html",
5 => "http://forum.cyberciti.biz/squid-monitoring-using-mrtg-vt5.html"
....
);
$top=$_GET['t'];
$u=$URLS[$top];
if ( isset($u)) {
  @include_once("../../include.genlib.php");
  movePage(301, "$u");
}
else
{
  @include_once("../../include.genlib.php");
  movePage(301, "http://forum.cyberciti.biz");
}
?>

Set a step value and generate a sequence number

In case, you are interested in my old (perhaps dirty) shell script 😉

#!/bin/bash
# Usage:
# ./script 1 5 +
# ./script 100 50 -
# where    START END +/-
FROM=$1
TO=$2
ACTION="$3"
if [ "$ACTION" == "+" ];
then
while [ $FROM -le $TO ]
do
  echo -n $FROM " "
  (( FROM++ ))
done
echo ""
else
while [ $FROM -ge $TO ]
do
  echo -n $FROM " "
  (( FROM-- ))
done
echo " "
fi

Run script as follows to set a step value and generate a sequence:
$ chmod +x script
$ ./script 5 10 +
$ ./script 20 10 -

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin and a trainer for the Linux operating system/Unix shell scripting. He has worked with global clients and in various industries, including IT, education, defense and space research, and the nonprofit sector. Follow him on Twitter, Facebook, Google+.

28 comment

  1. If you’re only printing 100 out of 10,000 files, you’ll be stuck in that loop for a while unless you break out of it:

    cnt=0; for i in *; do if [ $cnt -ge 100 ]; then break; else lp -d printer-name $i; fi; let cnt=cnt+1;done

  2. If you have many (I mean _many_) files in that directory, asterisk expansion may break limits of the command line length; in that case, simple listing combined with head would probably do better:

    ls | head -n 100 | lp -d printer-name

  3. I continue to use the ‘outdated’ seq command because of an option you didn’t mention:

    The -w option gives a sequence of numbers with equal width, by adding leading zeros if necessary.

  4. Can someone please edit this one,
    #!/bin/bash
    # Usage:
    # ./script 1 5 +
    # ./script 100 50 –
    # where START END +/-
    FROM=$1
    TO=$2
    ACTION=”$3″
    if [ “$ACTION” == “+” ];
    then
    while [ $FROM -le $TO ]
    do
    echo -n $FROM ” ”
    (( FROM++ ))
    done
    echo “”
    else
    while [ $FROM -ge $TO ]
    do
    echo -n $FROM ” ”
    (( FROM– ))
    done
    echo ” ”
    fi

    –instead of displaying it, it would be saved to a txt file. 🙂
    like this

    6001
    6002
    .
    I just need it for a dictionary file. Thank you.

  5. Hi,

    I need to create a calling script(main.sh) which would call another script (sub.sh). REquirement is as under :

    a) The sub.sh has few parameters like -U(i.e. username) -P(i.e. password) – R(i.e uniqueid)
    b) The -R parameter in sub.sh script has to be unique everytime it is run. This has to be handled in the main.sh script.
    c) In main.sh I need to generate a sequence and pass that vaue to the unique ID parameter in sub.sh. Everytime it should pass a unique value to sub.sh and execute sub.sh.

    Kindly help

  6. Please provide a script to print a numbers as 5,4,3,2,1.

    This is my program scripts, but the result got the numbers sequence not horizontally.

    numbers=5
    i=1
    while [ “$i” -le “$numbers” ]
    do
    echo “$i”
    i=$(( $i + 1 ))
    done

  7. Rupa$$ 3500 CSE
    Dharan 9000 CSE
    Madhu$ 9050 CSE
    Shivu$ 3500 EEE
    Vinay$ 6000 EEE
    Pramod 6500 EEE
    Harika 1050 ISE
    Ranjth 4000 ISE
    Agarwa 5600 ISE
    Preeti 1250 TCE
    Venuk$ 5877 TCE
    Chandi 9600 TCE

    =============================
    Can anyone help me out in printing first highest value,second value and least value in each department in the above table

Leave a Comment