Generate random numbers in specific range
You can try shuf
from GNU coreutils:
shuf -i 1-100 -n 1
In the POSIX toolchest, you can use awk
:
awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'
Do not use that as a source to generate passwords or secret data for instance, as with most awk
implementations, the number can easily be guessed based on the time that command was run.
With many awk
implementations, that command run twice within the same second will generally give you the same output.
jot
On BSD and OSX you can use jot to return a single random (-r
) number from the interval min
to max
, inclusive.
$ min=5
$ max=10
$ jot -r 1 $min $max
Distribution problem
Unfortunately, the range and distribution of randomly generated numbers is influenced by the fact that jot uses double precision floating point arithmetic internally and printf(3) for output format, which causes rounding and truncation issues. Therefore, the interval's min
and max
are generated less frequently as demonstrated:
$ jot -r 100000 5 10 | sort -n | uniq -c
9918 5
20176 6
20006 7
20083 8
19879 9
9938 10
On OS X 10.11 (El Capitan) this appears to have been fixed:
$ jot -r 100000 5 10 | sort -n | uniq -c
16692 5
16550 6
16856 7
16579 8
16714 9
16609 10
and...
$ jot -r 1000000 1 10 | sort -n | uniq -c
100430 1
99965 2
99982 3
99796 4
100444 5
99853 6
99835 7
100397 8
99588 9
99710 10
Solving the distribution problem
For older versions of OS X, fortunately there are several workarounds. One is to use printf(3) integer conversion. The only caveat is that the interval maximum now becomes max+1
. By using integer formatting, we get fair distribution across the entire interval:
$ jot -w %i -r 100000 5 11 | sort -n | uniq -c
16756 5
16571 6
16744 7
16605 8
16683 9
16641 10
The perfect solution
Finally, to get a fair roll of the dice using the workaround, we have:
$ min=5
$ max_plus1=11 # 10 + 1
$ jot -w %i -r 1 $min $max_plus1
Extra homework
See jot(1) for the gory math and formatting details and many more examples.