1. Introduction

Knowing how to print numbers within a range can come in handy in many ways. For one, if we want to populate our ansible hosts file with the IP addresses of our managed nodes, we can use commands like seq and printf. Using these commands as described can be pretty helpful when we have a long list of managed nodes since entering IP addresses manually would be exhausting.

In this tutorial, we’ll see four ways of printing numbers within a range in Linux.

2. Using seq

seq is perhaps the most popular command for printing numbers within a sequence in Linux, and it offers a fair number of options.

At its simplest, seq prints a range of numbers defined by the arguments passed to it.

When we pass just one argument to seq, it takes that argument as the last number in the range and 1 as the first number in the range:

$ seq 5
1
2
3
4
5

But, when we pass two arguments, the first argument would be the first number in the range while the second would be the last number in the range:

$ seq 6 10
6
7
8
9
10

Then, if we add a third argument, the argument in the middle would be the step or increment between each number in the range:

$ seq 6 2 10
6
8
10

The middle argument cannot be zero. If we use zero, we’ll get an error. Also, the arguments can only be numbers.

Besides –help and –version, seq has three options: -f, -s, and -w. Each one of these options alters the numbers that seq outputs in different ways.

2.1. The -f Option

The -f option is the format option. It directs the seq command to print the numbers in the sequence as floating point numbers. It’s also useful for adding a range of numbers to part of a larger string of numbers.

seq’s -f option takes two directives: %f and %g. While %f offers maximum precision (especially when the arguments are decimals), %g doesn’t.

Using seq -f and %f, we can print numbers between 40.1234 and 50.56789 while incrementing by 2.234:

$ seq -f %f 40.1234 2.234 50.56789
40.123400
42.357400
44.591400
46.825400
49.059400

Here’s our output from running the same sequence using %g:

$ seq -f %g 40.1234 2.234 50.56789
40.1234
42.3574
44.5914
46.8254
49.0594

As mentioned earlier, we can use the -f option to add a sequence to part of a larger string of numbers. Let’s illustrate this by printing a range of IP addresses:

$ seq -f "10.0.0.%g" 1 5
10.0.0.1
10.0.0.2
10.0.0.3
10.0.0.4
10.0.0.5

We can also redirect the IP addresses into a file, such as the hosts file:

$ seq -f "10.0.0.%g" 1 5 > hosts

2.2. The -s Option

The -s option defines the separator to use between each number in the range.

By default, the separator is \n, but we can make it whatever we want:

$ seq -s '*' 2 5
2*3*4*5

2.3. The -w Option

The -w option is the equal width option. It works by padding the numbers with preceding zeros. This way, all the numbers are printed with the same number of digits.

To illustrate this, we’ll print numbers between one and forty (inclusive) with a step size of nine:

$ seq -w 1 9 40
001
010
019
028
037

3. Using printf

We can use printf to generate a range of numbers by following a simple syntax:

$ printf '%s' {first number..last number}

Let’s print numbers between one and five inclusive:

$ printf '%s' {1..5}
12345

We can ensure each number is printed on a newline by adding \n to %s:

$ printf "%s\n" {1..5}
1
2
3
4
5

Then, if we want to increment the numbers in the range by two, we’ll add 2 to the curly braces:

$ printf "%s\n" {1..5..2}
1
3
5

In the printf commands above, %s instructs printf to treat its arguments as strings. Then, \n ensures printf uses a newline character as the delimiter between each output.

Unlike seq, printf does not work on decimals.

4. Using echo

The echo syntax is pretty similar to the printf syntax because they both use brace expansion. However, its default separator is a space character, while printf has no default separator.

Let’s start by printing numbers in the range of two to eight:

$ echo {2..8}
2 3 4 5 6 7 8

Let’s now print numbers from two to thirteen while incrementing each number by three:

$ echo {2..13..3}
2 5 8 11

Using tr, we can separate the numbers with a newline character:

$ echo {2..13..3} | tr " " "\n"
2
5
8
11

We can also use any other separator:

$ echo {2..13..3} | tr " " "-"
2-5-8-11

5. Using jot

jot is a command line tool used to print sequential or random data. In other words, its usefulness is not limited to numbers; it also works for letters.

We’ll start by installing jot on our Ubuntu machine:

$ sudo apt install athena-jot

Let’s review the jot command’s syntax:

$ jot [options] [number of data] [first number] [last number] [step size]

By default, the number of data or reps is 100, the first number is 1, the last number is 100, and the step size is 1.

A jot command can be as simple as printing all the numbers from one to five:

$ jot 5
1
2
3
4
5

But, we can also print six numbers between five and fifteen inclusive:

$ jot 6 5 15
5
7
9
11
13
15

When we specify the number of data elements we want from a range of numbers, jot tries to space out the selected numbers as much as possible. So, there may or may not be a recurring progression between the printed numbers.

Similar to what we did before, we can print all numbers from five to ten:

$ jot - 5 10 1
5
6
7
8
9
10

In the command above, ‘-‘ means that we’re not specifying the number of data (reps). In other words, we do not want only seven numbers between five and twenty; we want all the numbers we can get using a step size of one.

Omitting the step size in the command causes jot to use the default value of 100. This is why we had to specify it.

Let’s try printing all numbers in the range of 10 to 25 while incrementing by three:

$ jot - 10 25 3
10
13
16
19
22
25

jot also works with decimals:

$ jot - 10.1 30.8 3.5
10.1
13.6
17.1
20.6
24.1
27.6

We can also use the -p option to specify the number of decimal places we want:

$ jot -p3 - 10 25 3.232
10.000
13.232
16.464
19.696
22.928

Here, we specified three decimal places with -p3.

6. Conclusion

In this article, we went over four ways of printing a range of numbers on the Linux command line.

Besides the four options we discussed, we can also print number sequences using for loops and while loops. However, for potential performance gains, especially when working with larger number series, we avoid looping when possible.