$ seq 1 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
You can also specify an increment to use when generating numbers between
the start and end numbers. The syntax to use for including an increment is
seq start_num increment end_number
, where
start_num is the first number in the sequence, increment is the
number to be added to it to generate the next number, and end_number
is the last number in the sequence. E.g., for the sequence generated above,
I could also have used seq 1 1 15
to produce the same output,
since the default increment is 1. If I used an increment of 2 or 3,
I would see the following output:
$ seq 1 2 15 1 3 5 7 9 11 13 15 $ seq 1 3 15 1 4 7 10 13
You can see in the instance where the increment is 3, that the last number in the output is a number that is less than the ending number. I.e., the numbers output won't exceed the end number.
If the ending number given as an argument on the command line is less than the starting number and no increment is specified, then the numbers that are output will be in descending order from the ending number to the starting number with each succeeding number one less than the one before it.
$ seq 15 10 15 14 13 12 11 10
If you do specify an increment and the start number is less than the end number, then you need to use a negative number for the increment value.
$ seq 13 1 10 seq: needs negative decrement $ seq 13 -1 10 13 12 11 10 $ seq 13 -2 10 13 11 $
You can have leading zeros appear in a number, e.g., 01, instead of 1, by specifying a format for the numbers that will be output, just as you do with the printf command. E.g., if you wished to have numbers displayed as two digit numbers with a zero before the number if it would otherwise be only one digit, e.g., 01, 02, 03, instead of 1, 2, 3, then you could use a command similar to the one below.
$ seq -f "%02g" 1 15 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
The -f
indicates you want to specify a format for the output.
The percent sign within the double quotes indicates the start of the format
string. The zero followed by a two indicates you want a two digit field with
a leading zero, if needed to make the number appear as two digits. So, if you
needed a sequence of numbers for the days of the month for a month with 31 days
where the number always occupies two columns, you could use seq -f "%02g"
1 31
.
Likewise, if you wanted leading zeroes for a three digit output field, you could use a command like the one below.
$ seq -f "%03g" 1 15 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 $
If, instead, you wanted to have the numbers appear right-aligned in three columns, but without any leading zeros, you could use a format like the one below.
$ seq -f "%3g" 1 15 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
As an alternative to specifying the field width for the numbers with a
format string, you can use -w
to have leading zeros output if
needed to keep the field width consistent for all numbers. E.g., if I wanted
to produce numbers between 1 and 12 and have a leading zero output when needed
to make the field width two whether the number needed two or only one digits,
I could enter a command like the one below.
$ seq -w 1 12 01 02 03 04 05 06 07 08 09 10 11 12
If I changed the end number to 101, I wouldn't have to change a format
string, the -w
would ensure that every number was displayed as
3 digits to make each consistent with the number of digits used to display
the largest number in the sequence.
$ seq -w 1 101 001 002 003 004 005 006 007 008 009 010 011 012 013 < text snipped > 090 091 093 094 095 096 097 098 099 100 101
The numbers you use don't have to be integers. They can contain a fractional component.
$ seq -w 0 .05 .1 0.00 0.05 0.10 $ seq 1.0 0.01 1.15 1 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.1 1.11 1.12 1.13 1.14 $ seq -w 1.0 0.01 1.15 1.00 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.10 1.11 1.12 1.13 1.14
For the last two examples above where the starting number was 1.0 and the ending number was 1.15 with an increment of 0.01 used, you might expect that the last number output would be 1.15, but, instead, it is 1.14. The man page for seq states:
All numbers are interpreted as floating point.
I am presuming that occurs due to rounding occurring associated with the internal floating point representation of the numbers.
You can also include numbers in braces separated by two periods and use the echo command to produce numbers output on the same line, instead of on separate lines as is the default with the seq command.
$ echo {1..5} 1 2 3 4 5 $ echo {5..1} 5 4 3 2 1
If you wanted the numbers output by the
seq command to appear on the
same line, rather than separate lines, you could specify the separator with
the -s
option followed by a space enclosed in single or double
quotes.
$ seq -s " " 1 5 1 2 3 4 5 $
You will notice that in the above example with seq that, because there
is no
newline, i.e., no line break, after the last number output, that the
dollar sign for the
Bash shell prompt appears on the same line as the numbers output. I could
add a -t
parameter to specify a newline after the last number
output.
-t string Use string to terminate sequence of numbers. The string can contain character escape sequences in backslash nota- tion as defined in ANSI X3.159-1989 (``ANSI C89''). This option is useful when the default separator does not con- tain a \n.
E.g. to display the numbers from 1 to 5 on the same line, but then have the dollar sign shell prompt appear on the next line, I could use the following command:
$ seq -s " " -t "\n" 1 5 1 2 3 4 5 $
Enclosing numbers within braces, separated by two periods works to produce a sequence through "brace expansion" in the Bash shell. From the "Brace Expansion" section of the Bash man page:
Brace Expansion
Brace expansion is a mechanism by which arbitrary strings may be
generated. This mechanism is similar to pathname expansion, but
the filenames generated need not exist. Patterns to be brace
expanded take the form of an optional preamble, followed by either
a series of comma-separated strings or a sequence expression
between a pair of braces, followed by an optional postscript.
The preamble is prefixed to each string contained within the braces,
and the postscript is then appended to each resulting string,
expanding left to right.
Brace expansions may be nested. The results of each expanded string are not sorted; left to right order is preserved. For example, a{d,c,b}e expands into `ade ace abe'.
A sequence expression takes the form {x..y}, where x and y are either integers or single characters. When integers are supplied, the expression expands to each number between x and y, inclusive. When characters are supplied, the expression expands to each character lexicographically between x and y, inclusive. Note that both x and y must be of the same type.
Brace expansion can be used to generate a sequence of letters as well as numbers.
$ echo {a..m} a b c d e f g h i j k l m $ echo {m..a} m l k j i h g f e d c b a
You can also use brace expansion with the printf command to format numbers with leading zeros.
$ printf "%02g\n" {1..12} 01 02 03 04 05 06 07 08 09 10 11 12
In the example above, I included a \n
, which
represents a
newline, with the format specification, so that I could get each number on
a separate line. If I didn't inlude it, I would see the following output where
each number occurs immediately after the preceding one with no intervening
spaces.
$ printf "%02g" {1..12} 010203040506070809101112$
You can, of course, include other text with the brace expansion, for instance, if you wish to produce file names with sequential numbers at the end.
$ echo test{0..5}.txt test0.txt test1.txt test2.txt test3.txt test4.txt test5.txt
Or I could use the following to put each one on a separate line:
$ echo test{0..5}.txt\\n test0.txt test1.txt test2.txt test3.txt test4.txt test5.txt $
In the above case, when I appended the newline at the end of the echo command, I needed to use two backslash characters before the "n" to get the results I wanted. The first serves as an escape character for the second one. Otherwise I would see the following output:
$ echo test{0..5}.txt\n test0.txtn test1.txtn test2.txtn test3.txtn test4.txtn test5.txtn
I could use such a command with the touch command to generate empty files by those names on an OS X or Linux system using command substitution.
$ ls -l *.txt ls: *.txt: No such file or directory $ touch $(echo test{0..5}.txt\\n) $ ls -l *.txt -rw-r--r-- 1 jasmith1 wheel 0 May 6 17:07 test0.txt -rw-r--r-- 1 jasmith1 wheel 0 May 6 17:07 test1.txt -rw-r--r-- 1 jasmith1 wheel 0 May 6 17:07 test2.txt -rw-r--r-- 1 jasmith1 wheel 0 May 6 17:07 test3.txt -rw-r--r-- 1 jasmith1 wheel 0 May 6 17:07 test4.txt -rw-r--r-- 1 jasmith1 wheel 0 May 6 17:07 test5.txt $
Note: if you don't include the \n
for a newline character as
in the example above, you will get one file with one long name as shown below
when it is omitted:
$ touch "$(echo test{0..5}.txt)" $ ls -l *.txt -rw-r--r-- 1 jasmith1 wheel 0 May 6 16:26 test0.txt test1.txt test2.txt test3.txt test4.txt test5.txt $
I could also put the seq command in a for loop and use it to generate files with sequential numbers appended to the filenames.
$ ls *.tmp ls: *.tmp: No such file or directory $ for n in $(seq 1 5) > do > touch test${n}.tmp > done $ ls *.tmp test1.tmp test2.tmp test3.tmp test4.tmp test5.tmp $
In the above example, I typed the lines for the for loop at the shell prompt, rather than including them in a Bash script, which is why the greater than sign appears at the beginning of several lines as the Bash shell was prompting me for further input to complete the commands for the loop until I entered "done" to complete the for loop. To use the loop in a Bash script, I could put the following code in the script:
for n in $(seq 1 5) do touch test${n}.tmp done
If I wanted leading zeros for the numbers, I could just add the -w
option.
$ for n in $(seq -w 6 10) > do > touch test${n}.tmp > done $ ls *.tmp test06.tmp test08.tmp test1.tmp test2.tmp test4.tmp test07.tmp test09.tmp test10.tmp test3.tmp test5.tmp
Incidentally, if you wish to generate random numbers, instead of sequential numbers, to use in file names, you can use $RANDOM, which will return a random integer at each invocation. The nominal range is from 0 to 32,767 (signed 16-bit integer). E.g.
$ echo $RANDOM 6619 $ echo $RANDOM 16164 $ echo $RANDOM 26083 $
You can also use a for loop without seq or any other commands but echo to output a list of numbers. E.g., the following loop will output the numbers from zero to one less than ten, i.e., 0 to 9:
$ for (( i=0; i<10; i++ )) ; do echo $i ; done 0 1 2 3 4 5 6 7 8 9
Another alternative is to use a while loop.
counter=0 while [ $counter -lt 10 ] do echo $counter counter=`expr $counter + 1` done
Or, for either sequential or random numbers, you can use the
jot command. If you want to output the
natural
numbers, aka positive integers, from 1 to some number x, you
can use jot x
.
$ jot 5 1 2 3 4 5
You can have jot start at any number and output n numbers by
specifying jot values start_number
. E.g., to have
jot display 5 numbers starting at 24, you could use jot 5 12
.
$ jot 5 12 12 13 14 15 16
I could also start with a floating point number rather than an integer and have jot add one each time for five iterations. Jot will count using floating point numbers if a decimal point is included on the number.
$ jot 5 24.0 24.0 25.0 26.0 27.0 28.0 $ jot 5 24.2 24.2 25.2 26.2 27.2 28.2
As with the seq command, I can specify a
separator character with the -s
option. E.g., I could have
the numbers appear on the same line with a space between them using
-s " "
.
$ jot 5 1 2 3 4 5 $ jot -s " " 5 1 2 3 4 5
You can use the -r
option to generate a random number. To
generate one random number from 1 to 100, you can use jot
-r 1
. If you wanted five random numbers, you could use
jot -r 5
. If you aren't specifying the ending number, 100 will
be used.
$ jot -r 1 3 $ jot -r 1 17 $ jot -r 1 30 $ jot -r 5 18 50 82 44 4
You can specify the number of values to be produced and the starting and ending numbers as shown below:
$ jot -r 1 25 30 27 $ jot -r 5 25 30 26 30 28 27 28 $ jot -r 10 25 30 26 25 30 27 27 29 29 25 27 25 $
The first example generates one random number between 25 and 30, inclusive of the start and end numbers. The second example above generates 5 such numbers, and the third example generates 10 of them.
You can use the -b
option to repeat a string a specific number
of times:
$ jot -b hello! 3 hello! hello! hello! $
References: