0

With the shell script, I wish to generate five files, and I wish to put different random number range from 50000~150000 in each file. I tried something like following,

for i in 01 02 03 04 05; do
A=$((50000+100000))
B=$(($B%$A))
cat > ${i}.dat << EOF
AArandom=$A
EOF
done

But this does not work.... How can I make random numbers and print out for each file?

exsonic01
  • 615
  • 7
  • 27

2 Answers2

4

Each time you read the value of the variable $RANDOM, it gives you a random number between 0 and 2^15 - 1, that is 0 and 32767. So that doesn't give you enough range. You could use two $RANDOM as two digits of base-15, and then take appropriate modulo and apply appropriate range normalization.

Here's the logic wrapped in a function:

randrange() {
    min=$1
    max=$2

    ((range = max - min))

    ((maxrand = 2**30))
    ((limit = maxrand - maxrand % range))

    while true; do
        ((r = RANDOM * 2**15 + RANDOM))
        ((r < limit)) && break
    done

    ((num = min + r % range))
    echo $num
}

And then you can generate the files in a loop like this:

for i in 01 02 03 04 05; do
  echo "AArandom=$(randrange 50000 150000)" > $i.dat
done

Note that there is a caveat in the implementation of randrange: there is a loop to re-roll in case the value would be biased, but theoretically this may prevent the function from terminating. In practice, that's extremely unlikely, but deserves a mention.

janos
  • 120,954
  • 29
  • 226
  • 236
  • Nice solution to extend the range. The result is biased though, so you'll want to use a different construct if you want a completely uniform distribution. To see why, consider a range of 1 less than the highest number which can be handled by randrange, (2^15-1) * 2^15 + (2^15-1). Using that range there are exactly one combination of two `RANDOM` numbers resulting in each output number greater than 1, and *two* combinations resulting in 1 (one random number equal 0 and the other 1, or both numbers equal 2^15-1), making a result of 1 twice as likely as any other number. – l0b0 Jul 16 '17 at 10:40
  • @l0b0 good call, thanks. I think I corrected it, with the "minor" caveat that the program might never terminate if you have really bad luck =) – janos Jul 16 '17 at 11:11
  • RANDOM is a bash extension, it is not a general solution to getting a random number in a shell script. – John Eikenberry Aug 23 '21 at 23:12
2

shuf is probably what you want:

$ shuf -i 50000-150000 -n 1
148495
l0b0
  • 55,365
  • 30
  • 138
  • 223