Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question
    
when you say "unix", do you really mean Linux? Or are you really interested in portability to other systems (Solaris, BSD, ...)? –  glenn jackman May 28 '13 at 10:51
2  
s/range/seq - replace range with seq in your example. default separator is newline, to have spaces: seq -s " " 10 20 –  naxa May 28 '13 at 13:27
    
@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 May 28 '13 at 13:46
1  
This question should define what "standard unix program" means to OP. –  David Rivers May 28 '13 at 14:46
    
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 May 29 '13 at 18:48
show 1 more comment

7 Answers

up vote 76 down vote accepted

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
share|improve this answer
2  
sed 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 May 28 '13 at 9:43
2  
@scai you meant seq? –  Carlos Campderrós May 28 '13 at 10:09
    
@CarlosCampderrós Of course, unfortunately I can't edit my comment any more. –  scai May 28 '13 at 11:02
3  
seq 10 20 might also be a simple example worth adding ;) –  Oliver Salzburg May 28 '13 at 11:07
    
@scai that is awesome, I learnt something new today :) to be honest, I think you should add that as a separate, more detailed answer! –  timgws May 28 '13 at 14:14
add comment

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.

share|improve this answer
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 May 28 '13 at 7:13
    
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 May 28 '13 at 7:18
1  
@mpy, note that seq is a GNU utility, and therefore not a "standard unix program" –  glenn jackman May 28 '13 at 10:49
5  
@glennjackman According to developer.apple.com/library/Mac/documentation/Darwin/Reference/…... "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 May 28 '13 at 11:13
    
Also note that you can do for i in {001..010}; ... ; done and it will zero-pad the number to 3 digits. –  VolatileDream May 28 '13 at 15:16
show 1 more comment

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}'
share|improve this answer
1  
Don't you need to add /dev/null or < /dev/null to that? –  Scott May 28 '13 at 15:38
1  
@Scott No, this is not necessary. The POSIX standard ( pubs.opengroup.org/onlinepubs/9699919799/utilities/… ) 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 May 28 '13 at 20:40
add comment

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
share|improve this answer
add comment

Use a for loop

for ((i = 10; i <= 20; ++i)); do
    printf '%d\n' "$i"
done
share|improve this answer
add comment

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
share|improve this answer
add comment

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
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.