[Chapter 45] 45.11 The Multipurpose jot Command
Author: Jerry Peek, Tim O'Reilly & Mike Loukides
Date: 1998-08-04T21:54:32Z

#

| Chapter 45 Shell Programming for the Initiated |

## 45.11 The Multipurpose jot Command

The jot command is an extremely powerful tool for shell programming. People who have used jot end up using it all the time, but those who haven't been exposed to it may be perplexed by its function. For that reason, I think the best way to learn jot is by example. (If you've read many of my other articles, then you might notice that I think that example is the best way to learn anything; but for jot, it's doubly true!)

jot | In its most basic use, jot produces a series of numbers. With only one integer as a command-line argument, it produces the sequential integers from 1 to that number.

>     % jot 4
>     1
>     2
>     3
>     4

Big deal, you might say. Well, it may not be earth-shattering on the surface, but it can make your life much easier if you program in the Bourne shell. Take the instance when you want to increment a number in a loop. The usual way of doing this is:

>     counter=1
>     while [ $counter -le 10 ]
>     do
>        ...
>        counter=`expr $counter + 1`
>     done

This is laborious and quite slow. Because the Bourne shell doesn't have any built-in (1.10) number crunching, the only way to increment the counter is to use the expr command in each iteration of the loop. But if you have jot, the same loop can be written in a simple for loop:

>     for counter in `jot 10`
>     do
>        ...
>     done

You can also use jot to show any other sequence of numbers. For example, to show the integers between 24 and 28 (inclusive), try:

>     % jot 5 24
>     24
>     25
>     26
>     27
>     28

The first argument (5) is taken to be how many values should be shown. The second number (24) is the number to start counting with. This may seem frustrating - why not just let us say "jot 24 28" to specify the beginning and end of the sequence, rather than make us figure out how many numbers will be in the sequence first? Well, the reason is that you might not always want to be counting by whole numbers.

If supplied with a third argument, jot takes it as the number to end the sequence with. And if you specify either the beginning or end boundary with a decimal point, it will produce fractional numbers in its output:

>     % jot 5 24 28.0
>     24.0
>     25.0
>     26.0
>     27.0
>     28.0
>     % jot 4 24 28.0
>     24.0
>     25.3
>     26.7
>     28.0

You can also use the -p option to specify a given precision:

>     % jot -p4 4 24 28
>     24.0000
>     25.3333
>     26.6667
>     28.0000

By default, the values shown are evenly spaced across the interval. You can change this by using a fourth numerical argument, which becomes the size of each step in the iteration. For example:

>     % jot 4 24 28.0 .5
>     24.0
>     24.5
>     25.0
>     25.5

Notice in this example that only the first four iterations are shown, because we asked for only four values in the first argument. This is because any three values determine the fourth automatically, so when the values conflict, jot takes the lower value. jot stopped after four values regardless of the fact that it would need nine iterations to complete the sequence. However, jot will also stop if the sequence is completed before the specified number of values are shown.

>     % jot 4 24 28 2
>     24
>     26
>     28

To omit any of these values, replace them with a single dash (`-`). For example, if you know that you just want the digits from 24 to 28, you can omit the field specifying the number of values as long as you tell it to use a step of 1:

>     % jot - 24 28 1
>     24
>     25
>     26
>     27
>     28

And of course, you can use negative numbers and negative steps:

>     % jot - 1 -3 -2
>     1
>     -1
>     -3

If you want the output separated by a string other than a newline, use the -s option. For example, to have the output of the previous command separated by spaces, enter:

>     % jot -s " " - 1 -3 -2
>     1 -1 -3

That's jot in its no-frills form, already potentially useful for any writer of shell scripts. However, jot does quite a lot more. The -c option can be used to show ASCII (51.3) characters instead of integers. To print out the character for ASCII 65 (decimal), for example, try:

>     % jot -c 1 65
>     A

You can also do the ASCII-to-decimal conversion in reverse, by just specifying a character in place of the lower bound:

>     % jot 1 A
>     65

This can be handy if you want an automatic listing of all 26 letters:

>     % jot -c 26 A
>     A
>     B
>     C
>        ...

The -r option produces random numbers, which is very useful in shells with no random number generator (such as the Bourne or C shells). To create a 6-digit random number, try:

>     % jot -r 1 100000 999999
>     523467

(Using -r, the fourth numerical argument, if specified, is taken to be a seed for the random number.)

The -b option can be used to repeat a given word, much like the yes (23.4) command:

>     % jot -b lunchtime! 3
>     lunchtime!
>     lunchtime!
>     lunchtime!

The jot manual page suggests a clever way of using this feature: if you want to search for lines in files that have 40 or more characters, you could do this using regular expressions, but you'd have to count out all those dots.

>     grep "........................................" file

Using jot, you can pat yourself on the back for being ingenious (or for just reading the manpage!):

>     grep `jot -s "" -b . 40` file

But the most powerful feature of jot comes with its -w option. The -w option accepts a word containing format conversion characters as used by the printf( ) function. (For example, `%d` prints a decimal argument; `%h` prints hexadecimal.) If you aren't familiar with the printf( ) format conversions, read your printf(3) manual page or check any C programming book.

This allows you to combine strings with jot output, a useful feature for manipulating temporary files within scripts. For example, suppose you have a shell script that creates multiple temporary files that you want to remove at the end of the script. You might have even created the files using jot earlier in the script, as shown previously:

>     for counter in `jot 10 1`
>     do
>        whatever commands > tmp$counter
>     done

Then later on you want to remove the files. You could do another loop, but it's more efficient to just enter:

>     rm `jot -w tmp%d 10 1`

The jot command expands to the strings tmp1 through tmp10, which are the names of the temporary files created earlier in the script.

- LM

45.10 Removing a File Once It's Opened - for Security and Easy Cleanup |  | 45.12 Parameter Substitution