Bash script number generator

I need to generate random numbers in a specific format as test data. For example, given the number "n", I need to create "n" random numbers and write them to a file. The file should contain no more than 3 digits per line. Here is what I have:

#!/bin/bash

m=$1
output=$2

for ((i=1; i<= m; i++)) do
    echo $((RANDOM % 29+2)) >> $output
done

This displays the numbers as:

1
2
24
21
10
14

I want too:

1 2 24
21 10 14

Thank you for your help!

+4
source share
6 answers

Pure bash (written as a function, not a script file)

randx3() {
  local d=$'  \n'
  local i
  for ((i=0;i<$(($1 - 1));++i)); do
    printf "%d%c" $((RANDOM%29 + 2)) "${d:$((i%3)):1}"
  done
  printf "%d\n" $((RANDOM%29 + 2))
}

Note that it does not accept a file argument; rather, it outputs to stdout, so you will use it like this:

randx3 11 > /path/to/output

This style is often more flexible.

Here's a less hacky one that allows you to choose how often you want to use the new line:

randx() {
  local i
  local m=$1
  local c=${2:-3}
  for ((i=1;i<=m;++i)); do
    if ((i%c && i<m)); then
      printf "%d " $((RANDOM%29 + 2))
    else
      printf "%d\n" $((RANDOM%29 + 2))
    fi
  done
}

randx 11 randx 11 7 ( 3).

+3

, 3 :

for ((i=1; i<= m; i++)) do
    echo $((RANDOM % 29+2))
done | sed -e '$!N;$!N;s/\n/ /g' >> $output
+3

, paste :

$ for i in {0..10}; do echo $RANDOM; done | paste -d' ' - - -
14567 3240 16354
17457 25616 12772
3912 7490 12206
7342 10554 

, printf.

m=$1
output=$2
vals=()
while (( m-- )); do
  vals+=( $((RANDOM % 29+2)) )
done
printf '%d %d %d\n' "${vals[@]}" > "$output"
+1

YAS: bash

m=$1
output=$2
out=()
for ((i=1;i<=m;i++));do
    out+=($((RANDOM%29+2)))
    [ $((i%3)) -eq 0 ] && echo ${out[*]} >>$output && out=()
  done
[ "$out" ] && echo ${out[*]} >>$output

RANDOM%29

2 30 :

$RANDOM 0 32767, :

for ((i=0;i<32768;i++)) ;do
    ((RL[$((i%29+2))]++))
  done
for ((i=0;i<32;i++));do
    printf "%3d %5d\n" $i ${RL[i]}
  done | column 

  0     0     7  1130        14  1130        21  1130        28  1130
  1     0     8  1130        15  1130        22  1130        29  1129
  2  1130     9  1130        16  1130        23  1130        30  1129
  3  1130    10  1130        17  1130        24  1130        31     0
  4  1130    11  1130        18  1130        25  1130
  5  1130    12  1130        19  1130        26  1130
  6  1130    13  1130        20  1130        27  1130

, 1130 2 28, 1129 29 30.

, :

random2to30() {
    local _random=32
    while [ $_random -gt 28 ] ;do
        _random=$((RANDOM & 2#11111)) # return 5 bit random 0 to 31
      done
    printf -v $1 "%d" $((2+_random))  # Assign variable to prevent forks
}

:

tstr2to30() {
    unset $1
    local _random=32
    while [ $_random -gt 28 ] && read _random ;do
        _random=$((_random& 2#11111))
      done
    [ "$_random" ] && printf -v $1 "%d" $((2+_random))
}
unset RL
while tstr2to30 MyRandom && [ "$MyRandom" ] ;do
    ((RL[MyRandom]++))
  done < <(seq 0 32767)
for ((i=0;i<32;i++));do
    printf "%3d %5d\n" $i ${RL[i]}
  done | column 

Give:

  0     0    7  1024        14  1024        21  1024        28  1024
  1     0    8  1024        15  1024        22  1024        29  1024
  2  1024    9  1024        16  1024        23  1024        30  1024
  3  1024   10  1024        17  1024        24  1024        31     0
  4  1024   11  1024        18  1024        25  1024
  5  1024   12  1024        19  1024        26  1024
  6  1024   13  1024        20  1024        27  1024

(1024) .

script

, script ( bash shebang!):

#!/bin/bash

m=${1:-11}                  # default to 11 values
output=${2:-/dev/stdout}    # default to STDOUT
c=${3:-3}                   # default to 3 values by lines

random2to30() {
    local _random=32
    while [ $_random -gt 28 ] ;do
        _random=$((RANDOM & 2#11111)) # return 5 bit random 0 to 31
      done
    printf -v $1 "%d" $((2+_random))  # Assign variable to prevent forks
}

out=()
for ((i=1;i<=m;i++));do
    random2to30 MyRandom
    out+=($MyRandom)
    [ $((i%c)) -eq 0 ] && echo ${out[*]} >>"$output" && out=()
  done
[ "$out" ] && echo ${out[*]} >>"$output"
+1

This awk inserts a new line after every third line or space:

for ((i=1; i<= m; i++)); do
    echo $((RANDOM % 29+2))
done | awk '{printf "%s%c", $1, (NR % 3) ? " " : "\n"}' >> $output
0
source

another way to do this:

eval echo {1..$m} | xargs -n3 echo $((RANDOM % 29+2)) > $output
0
source

All Articles