有:
mapfile -t words < <( head -10000 /usr/share/dict/words)
echo "${#words[@]}" #10000
r=$(( $RANDOM % ${#words[@]} ))
echo "$r ${words[$r]}"
这从10k字的数组中选择一个随机字。
但是如果数组大32767(例如整个文件200k +单词),它会停止工作,因为$RANDOM
最多只有32767.来自man bash
:
每次引用此参数时,都会生成0到32767之间的随机整数。
mapfile -t words < /usr/share/dict/words
echo "${#words[@]}" # 235886
r=$(( $RANDOM % ${#words[@]} )) #how to change this?
echo "$r ${words[$r]}"
不要使用像perl -plE 's/.*/int(rand()*$_)/e'
这样的perl,并不是每个系统都安装了perl。寻找最简单的解决方案 - 也不关心真正的随机性 - 它不适用于加密。 :)
答案 0 :(得分:1)
如果您的系统上有shuf
...
r=$(shuf -i 0-${#words[@]} -n 1)
如果没有,您可以多次使用$RANDOM
并连接结果以获得足够数字的数字来满足您的需求。你应该连接,而不是添加,因为添加随机数不会产生均匀分布(就像投掷两个随机模具将产生总共7个而不是总共1个)。
例如:
printf -v r1 %05d $RANDOM
printf -v r2 %05d $RANDOM
printf -v r3 %05d $RANDOM
r4=${r1:1}${r2:1}${r3:1}
r=$(( $r4 % ${#words[@]} ))
printf
语句用于确保保留前导零; -v
选项是一个隐藏的gem,它允许为变量赋值(除了其他功能之外,它允许在许多有用的实际案例中避免使用eval
)。 r1
,r2
和r3
各自的第一个数字被删除,因为它只能是0,1,2或3。
答案 1 :(得分:1)
一种可能的解决方案是使用$RANDOM
的结果进行一些数学运算:
big_random=`expr $RANDOM \* 32767 + $RANDOM`
另一种方法是使用$RANDOM
一次选择输入文件的块,然后再次使用$RANDOM
从该块中选择一行。
请注意,$RANDOM
不允许您指定范围。 %
给出了不统一的结果。进一步讨论:How to generate random number in Bash?
顺便说一句,将整个words
读入记忆中并不是特别明智。除非您要对此数据结构进行大量重复访问,否则请考虑尝试在不立即填充整个文件的情况下执行此操作。
答案 2 :(得分:0)
接受的答案将为您提供10位数字,但是对于每个5位数字的前缀,后5位数字只能在00000-32767
范围内。
例如,1234567890
不可能是数字67890 > 32767
。
可能很好。我个人觉得这个选项更好。它为您提供数字0-1073676289
,没有空格。
big_random=$(expr $RANDOM \* $RANDOM)