Is there a standard unix program that returns a range of numbers

22

3

Im learning shell scripting from an outdated textbook, and it seems to me like it'd be really usefull to have a program that just returns a string of numbers delimited by spaces something like

$ range 10 20
10 11 12 13 14 15 16 17 18 19 20

Then, if youre doing a shell script you can have

for i in `range 10 20`; do some stuff with numbers in that range;done

does such a thing exist, or do I need to write it myself?

MYV

Posted 2013-05-28T06:46:12.770

Reputation: 1 003

when you say "unix", do you really mean Linux? Or are you really interested in portability to other systems (Solaris, BSD, ...)? – glenn jackman – 2013-05-28T10:51:55.663

2s/range/seq - replace range with seq in your example. default separator is newline, to have spaces: seq -s " " 10 20 – n611x007 – 2013-05-28T13:27:58.673

@naxa Whether it's spaces or newlines does not matter in the for loop—or even any general command that splits arguments—unless you've set the IFS differently. – slhck – 2013-05-28T13:46:42.027

1This question should define what "standard unix program" means to OP. – David Rivers – 2013-05-28T14:46:57.923

I say unix because im learning linux from the book "The Unix Programming Environment" by pike (I know its dated, but I like it). – MYV – 2013-05-29T18:48:04.273

1As @DavidRivers already commented, you should state in the title and the question your focus is on Linux distributions. The answer you accepted suggests a tool which is NOT a standard Unix program. Several Unix are lacking seq as it is not specified by POSIX. – jlliagre – 2013-08-22T15:32:26.467

Answers

79

seq is part of coreutils.

for i in $( seq 1 2 11 ) ; do echo $i ; done

Output:

1
3
5
7
9
11

If you provide only 2 arguments to seq, the increment is 1:

$ seq 4 9
4
5
6
7
8
9

choroba

Posted 2013-05-28T06:46:12.770

Reputation: 14 741

2sed also has nice options like -s to set the separator or -w to qualize the width. And you can provide an increment: seq -w -s ", " 0 5 20 results in

00, 05, 10, 15, 20. – scai – 2013-05-28T09:43:18.753

2@scai you meant seq? – Carlos Campderrós – 2013-05-28T10:09:07.463

@CarlosCampderrós Of course, unfortunately I can't edit my comment any more. – scai – 2013-05-28T11:02:22.877

3seq 10 20 might also be a simple example worth adding ;) – Der Hochstapler – 2013-05-28T11:07:09.317

@scai that is awesome, I learnt something new today :) to be honest, I think you should add that as a separate, more detailed answer! – Tim Groeneveld – 2013-05-28T14:14:40.010

33

Would Bash suffice?

for i in {10..20}; do echo $i; done

You can do a lot of things with brace expansion. Bash 4 also supports padded ranges, e.g. {01..20}.

Note that Bash is not considered portable, and not a standard Unix utility. Although you can safely assume that it is installed on most modern Linuxes, don't use this in a script that you plan to run on all kinds of Unix-like machines.

slhck

Posted 2013-05-28T06:46:12.770

Reputation: 182 472

13@Maksim: Although I also prefer this brace expansion, there's also a typical Un*x tool (do very little, but do that well) for that: seq. The usage is as in your example: seq -s " " 10 20. The -s parameter is necessary, because by default the values are separated by \n. – mpy – 2013-05-28T07:13:31.870

Yeah, Bash isn't "standard" depending on how strict you interpret that. I just find it easier to handle and it doesn't require an extra call. – slhck – 2013-05-28T07:18:43.887

1@mpy, note that seq is a GNU utility, and therefore not a "standard unix program" – glenn jackman – 2013-05-28T10:49:55.060

5

@glennjackman According to http://developer.apple.com/library/Mac/documentation/Darwin/Reference/ManPages/man1/seq.1.html... "The seq command first appeared in Plan 9 from Bell Labs. A seq command appeared in NetBSD 3.0, and ported to FreeBSD 9.0. This command was based on the command of the same name in Plan 9 from Bell Labs and the GNU core utilities. The GNU seq command first appeared in the 1.13 shell utilities release."

– 200_success – 2013-05-28T11:13:43.810

Also note that you can do for i in {001..010}; ... ; done and it will zero-pad the number to 3 digits. – VolatileDream – 2013-05-28T15:16:36.710

@jex That's what I mentioned: "Bash 4 also supports padded ranges". – slhck – 2013-05-28T15:37:48.273

9

If you want something strictly portable (i.e. that does not rely on specific bash extensions or commands not specified by POSIX)

awk 'BEGIN {for(i=10;i<=20;i++) printf "%d ",i; print}'

jlliagre

Posted 2013-05-28T06:46:12.770

Reputation: 12 469

1Don't you need to add /dev/null or < /dev/null to that? – Scott – 2013-05-28T15:38:55.893

1

@Scott No, this is not necessary. The POSIX standard ( http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html#tag_20_06_06 ) specifies: If the awk program contains no actions and no patterns, but is otherwise a valid awk program, standard input and any file operands shall not be read and awk shall exit with a return status of zero.

– jlliagre – 2013-05-28T20:40:19.550

6

Before 10.7 there was no seq on Mac OS X, but jot, due to the BSD heritage.

jot -- print sequential or random data

...

HISTORY
    The jot utility first appeared in 4.2BSD

Example:

$ jot - 1 3
1
2
3

miku

Posted 2013-05-28T06:46:12.770

Reputation: 422

2

Use a for loop

for ((i = 10; i <= 20; ++i)); do
    printf '%d\n' "$i"
done

user27076

Posted 2013-05-28T06:46:12.770

Reputation: 234

2

You can use seq, or if you don't have that, you can write it yourself:

#!/bin/bash
[ $# -ge 1 ] || { echo "Usage: seq Number [ Number ]" 1>&2 ; exit 1; }
[ $# -eq 1 ] && { [ $1 -gt 1 ] && ./seq $(($1 - 1)) ; echo $1 ; }
[ $# -eq 2 ] && { [ $(($2 - $1)) -gt 0 ] && ./seq $1 $(($2 - 1)) ; echo $2 ; }

Usage:

$ ./seq 3
1
2
3

Or:

$ ./seq 3 7
3
4
5
6
7

StackedCrooked

Posted 2013-05-28T06:46:12.770

Reputation: 2 525

1

For the sake of completeness here something that will work with some older variants of Unix (as long as they have perl installed). Not really elegant.

for I in $(perl -e 'print join("\n", 1..10)'); do something with $I; done

reto

Posted 2013-05-28T06:46:12.770

Reputation: 416