经过一番谷歌搜索之后,我找不到一种简单的方法来使用Shell命令来生成包含在特定范围内的随机十进制整数,该范围介于最小值和最大值之间。

我读到了有关/dev/random/dev/urandom$RANDOM,但是这些都不能满足我的需要。

是否还有另一个有用的命令或使用先前数据的方法?

评论

请参阅以下SO Q&A:stackoverflow.com/questions/8988824/…以及此stackoverflow.com/questions/2556190/…。

可能相关:unix.stackexchange.com/questions/42045/random-number-needed / ...

相关:unix.stackexchange.com/questions/124478/…

#1 楼

在POSIX工具箱中,您可以使用awk

awk -v min=5 -v max=10 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'


请勿将其用作生成密码或机密数据的源,例如,与大多数awk实现一样,

对于许多awk实现,该命令在同一秒内运行两次通常会为您提供相同的输出。

评论


+1 ..在脚本中用于将输出分配给变量(不引入换行符并在两个位置使用零填充):x = $(awk -v min = $ min_var -v max = $ max_var' BEGIN {srand(); printf(“%。2d”,int(min + rand()*(max-min + 1))}'))

–克里斯托弗(Christopher)
19年4月22日在18:35



它是基于时间的?因为我连续2次获得相同的值...

–Shai Alon
19年5月5日在14:13

@ShaiAlon当前时间通常用作srand()的默认种子值,因此通常,是的,它是基于时间的,请参见他的答案中Stéphane的句子。您可以通过使用awk将初始种子更改为随机数来解决该问题-v min = 5 -v max = 10 -v seed =“ $(od -An -N4 -tu4 / dev / urandom)”'BEGIN {srand (种子+0);打印int(min + rand()*(max-min + 1))}'。您可以使用$ RANDOM代替od ... / dev / random,但是您的种子值在0到32767的相对较小范围内,因此随着时间的推移,您的输出中可能会出现明显的重复。

–埃德·莫顿(Ed Morton)
19年8月9日在17:54

#2 楼

您可以从GNU coreutils尝试shuf

shuf -i 1-100 -n 1


评论


这也适用于Busybox shuf。

– cov
18年5月30日在14:11

也可以在raspbian和GitBash中使用。

– nPcomp
18-10-22在17:55



即使使用“ -n 500”,它也只能为我创建101行

–SadikÖzoguz
20年7月4日,0:14

-n 1部分从1到100编号行的文本列表中选择“ top”行。如果需要101个编号,则需要运行101次。

–迈克尔·J·埃文斯(Michael J. Evans)
20-09-6的1:38

shuf -i 1000-9999 -n 256 -o file_name.txt-生成从1000到9999的唯一256个数字并将其保存到名为file_name.txt的文件中。

–谢尔盖·涅姆奇诺夫(Sergey Nemchinov)
20 Sep 14'6:46



#3 楼

jot

在BSD和OSX上,您可以使用jot从间隔-rmin(含)返回单个随机(max)数字。

$ min=5
$ max=10
$ jot -r 1 $min $max


分布问题

不幸的是,随机生成的数字的范围和分布受到以下事实的影响:jot在内部使用双精度浮点算术并且将printf(3)用作输出格式,这会导致舍入和截断问题。因此,生成间隔的minmax的频率降低,如下所示:

$ jot -r 100000 5 10 | sort -n | uniq -c
9918  5
20176 6
20006 7
20083 8
19879 9
9938  10


在OS X 10.11(El Capitan)上,此问题似乎已解决:

$ jot -r 100000 5 10 | sort -n | uniq -c
16692 5
16550 6
16856 7
16579 8
16714 9
16609 10  


和...

$ 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


解决发行问题

对于旧版本OS X,幸运的是,有几种解决方法。一种是使用printf(3)整数转换。唯一的警告是最大间隔现在变为max+1。通过使用整数格式,我们可以在整个时间间隔内公平分配:

$ jot -w %i -r 100000 5 11 | sort -n | uniq -c
16756 5
16571 6
16744 7
16605 8
16683 9
16641 10


完美的解决方案

最后,获得合理的收益使用解决方法的骰子,我们有:

$ min=5
$ max_plus1=11  # 10 + 1
$ jot -w %i -r 1 $min $max_plus1


额外的作业

请参见jot(1)以获取详细的数学和格式设置细节以及许多其他内容更多示例。

#4 楼

$RANDOM变量通常不是生成良好随机值的好方法。还需要首先转换/dev/[u]random的输出。

一种更简单的方法是使用高级语言,例如python:

要生成5到10之间的随机整数变量(5 <= N <= 10),请使用

python -c "import random; print random.randint(5,10)"


不要将此用于加密应用程序。

评论


这很有用。非常感谢:)正如Unix-> Solaris 10上经常使用的签名一样,默认情况下不集成GNU utils。但是,这有效。

–功能
17-2-22在10:29

#5 楼

您可以通过urandom获取随机数

head -200 /dev/urandom | cksum

输出:

3310670062 52870

取上面的数字。

head -200 /dev/urandom | cksum | cut -f1 -d " "

然后输出为

3310670062

评论


head -200(或等效于POSIX的head -n 100)返回/ dev / urandom的前200行。 / dev / urandom不是文本文件,该命令可以从200个字节(全为0x0a,ASCII中为LF)返回到无穷大(如果从不返回0xa字节),但最有可能介于45k和55k之间。 cksum返回一个32位数字,因此从/ dev / urandom中获取4个以上的字节毫无意义。

–StéphaneChazelas
19/09/10在11:30

#6 楼

若要生成5到10(包括两者)之间的随机整数变量,请使用

echo $(( RANDOM % (10 - 5 + 1 ) + 5 ))


%用作模运算符。

有将随机变量$RANDOM转换为特定范围的更好的方法。请勿将其用于加密应用程序,或者在您需要真实,平均分布的随机变量(例如用于模拟)的情况下。

评论


在许多确实具有$ RANDOM的shell实现中(尤其是较旧的,尤其是bash),这不是很随机。在大多数shell中,该数字在0到65535之间,因此宽度不为2的幂的任何范围将具有概率分布差异。 (在这种情况下,数字5至8的概率为10923/65536,而数字9和10的概率为10922/65536)。范围越宽,差异越大。

–StéphaneChazelas
2014年7月4日在12:39

抱歉,这是32767而不是65535,因此上面的计算是错误的(实际上更糟)。

–StéphaneChazelas
2014年7月4日13:05

@StéphaneChazelas当我写到有更好的方法时,我想到了这一点。

– jofel
2014年7月4日在13:27

#7 楼

# echo $(( $RANDOM % 256 ))将在现代* sh方言中产生一个介于0-255之间的“随机”数字。

评论


看起来类似于2年前的其他答案。

– Jeff Schaller♦
16年11月24日在5:24

如果您使用的值不是256,而不是256,而不是256,则会遇到信鸽问题(TL; DR:某些结果比其他结果更有可能)。

–toon81
16-11-28在12:52

#8 楼

也许UUID(在Linux上)可用于检索随机数

$ cat /proc/sys/kernel/random/uuid
cdd52826-327d-4355-9737-895f58ad11b4


获取70100之间的随机数

POSIXLY_CORRECT=1 awk -F - '{print(("0x") % 30 + 70)}
   ' /proc/sys/kernel/random/uuid


#9 楼

cat /dev/urandom | tr -dc 'a-fA-F0-9' | fold -w 8 | head -n 1


这将生成一个8位长的十六进制数字。

#10 楼

若要完全使用bash并使用$ RANDOM变量,但要避免分布不均:

#!/bin/bash
range=10 
floor=20

if [ $range -gt 32768 ]; then
echo 'range outside of what $RANDOM can provide.' >&2
exit 1 # exit before entering infinite loop
fi 

max_RANDOM=$(( 2**15/$range*$range ))
r=$RANDOM
until [ $r -lt $max_RANDOM ]; do
r=$RANDOM
done
echo $(( r % $range + $floor ))


本示例将提供20到29之间的随机数。

#11 楼

分布良好:对于((i = 1; i <= 100000; i ++))做回声$((RANDOM%(20-10 + 1)+ 10));完成|排序-n | uniq -c

计数值

9183 10

9109 11

8915 12

9037 13

9100 14

9138 15

9125 16


9088 18

8996 19

9048 20

#12 楼

使用RANDOM

MAX=999999                      #Upper Range
MIN=100000                      #Lower Range
DIFF=$((MAX-MIN+1))             #+1 to inlcude upper limit
R=$(($(($RANDOM%$DIFF))+MIN))


使用SHUF

MIN=1000
MAX=9999
COUNT=1                         #count of Random Numbers to be generated
shuf -i $MIN-$MAX -n $COUNT
shuf -i 1000-9999 -n 1


使用/ dev / random


od -An -N2 -i /dev/random       #Generates a 2 byte Number, -N2=Generates 2 Random Number btween range 0-65535


评论


您的DIFF为-899998,而$ RANDOM仅涵盖0-32767

–frostschutz
20年1月29日在15:33

@frostschutz,纠正了错字。

– Aashutosh
20年1月29日在15:38