Bash随机数生成器,其中number不在数组中

时间:2012-01-03 01:20:21

标签: arrays bash random numbers

我正在尝试创建一个随机数生成器,它生成1到99之间的数字,但不会生成任何已生成的数字。

在脚本中,array1包含已生成的数字。为了使测试更容易,我将随机数范围缩小到0-14并手动创建了一个数组。

我很擅长使用脚本编写脚本并使用几本书和互联网进行搜索。

我尝试了各种各样的想法,似乎最有意义的是

array1=( 1 2 3 6 7 8 9 10 11 12 13 )
func1() {
    for var in "${array1[@]}"
    do
      echo $var
    done
}
rnd=$[ $RANDOM % 14 ]
until [ $rnd != func1 ]
    do
        rnd=$[ $RANDOM % 14 ]
    done
echo $rnd

但是我知道问题出在第9行,shell看到以下代码:

until [ $rnd != 1 2 3 6 7 8 9 10 11 12 13 ]

我知道解决方案是第9行需要:

until [ $rnd != 1 ] && [ $rnd != 2 ] && [ $rnd != 3 ] && ...

我只是不知道如何从阵列中自动发生这种情况。根据生成的数量,数组的长度会有所不同。

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:1)

这是我在bash中遇到的困难。我想出的方法是让func1()返回true或false并修改数组以删除已选择的数字。

array=( {1..15} )
func1() {
   local pick="$1"
   found=1
   total=${#array[@]}
   for ((i=0;i<total;i++)); do 
      if (( pick == ${array[i]} )); then
         echo $pick
         array=( ${array[@]:0:i} ${array[@]:((i + 1)):$total})
         found=0
         break
      fi
   done
   return $found
}
numbers=3
for ((x=0;x<numbers;x++)); do 
   until func1 $(( $RANDOM % ( ${#array[@]} ) )); do 
      continue 
   done 
done

答案 1 :(得分:1)

如其中一条评论中所述,使用Knuth Shuffle是一种很好的方法

#!/bin/bash

shuffle() {
   local i tmp size max rand
   # Code from http://mywiki.wooledge.org/BashFAQ/026
   # $RANDOM % (i+1) is biased because of the limited range of $RANDOM
   # Compensate by using a range which is a multiple of the array size.
   size=${#array[*]}
   max=$(( 32768 / size * size ))

   for ((i=size-1; i>0; i--)); do
      while (( (rand=$RANDOM) >= max )); do :; done
      rand=$(( rand % (i+1) ))
      tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
   done
}

# Fill an array with values 1 to 99
array=({1..99});

# Shuffle the array at random
shuffle

# Echo shuffled array
echo ${array[@]}

输出

$ ./knuth
58 78 6 37 84 79 81 43 50 25 49 56 99 41 26 15 86 11 96 90 76 46 92 70 87 27 33 91 1 2 73 97 65 69 42 32 39 67 72 52 36 64 24 88 60 35 83 89 66 30 4 53 57 28 75 48 40 74 18 23 45 61 20 31 21 16 68 80 62 8 98 14 7 19 47 55 22 85 59 17 77 10 63 93 51 54 95 82 94 9 44 38 13 71 34 29 5 3 12

答案 2 :(得分:0)

如果-R的版本支持sort,您还可以使用sort切换到for x in {1..99} ; do echo $x ; done | sort -R

{{1}}