2017-07-16 113 views
0

使用shell脚本,我希望生成五个文件,并且我希望在每个文件中放置从50000到150000的不同随机数范围。我试过类似以下的东西,如何在shell脚本中使用随机数字?

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

但是这不起作用....我怎样才能使随机数字和打印出每个文件?

+0

@Steve没有重复,因为范围要求:'$ RANDOM'产生号码'0的范围内 - 32767',但在这里,一个更大的范围需要。 – janos

+0

如果你想在bash中做些什么,“man bash”往往是一个很好的开始。手册页很长;搜索关键字,就像'随机'... –

+0

我认为这个问题应该重写,以明确注意范围> 32767的要求。 –

回答

5

每次读取变量$RANDOM的值时, 它给你 是0和32767这样不给你足够的范围在0和2^15 - 1之间的随机数。 您可以使用两个$RANDOM作为基数15的两位数字, ,然后采用适当的模数并应用适当的范围归一化。

这里是包裹在一个函数的逻辑:

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 
} 

然后你就可以在这样的循环生成文件:

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

注意存在的randrange执行情况的警告: 如果数值有偏差,有一个重新滚动的循环,但理论上这可能会阻止函数终止。 实际上,这是不太可能的,但值得一提。

+0

扩大范围的好解决方案。结果是有偏见的,所以如果你想要一个完全一致的分布,你会想要使用不同的结构。为了明白为什么,考虑一个比randrange(2^15-1)* 2^15 +(2^15-1)可以处理的最高数小1的范围。使用该范围时,只有两个“RANDOM”数字组合导致每个输出数大于1,而*两个*组合导致1(一个随机数等于0,另一个等于0,另一个数等于2^15- 1),其结果是其他数字的两倍。 – l0b0

+0

@ l0b0很好的电话,谢谢。我认为我已经纠正了这个问题,并提供了一个“次要”警告,即如果你的运气真的很糟糕,程序可能永远不会终止) – janos

1

shuf可能是你想要什么:

$ shuf -i 50000-150000 -n 1 
148495 
+0

不错,简单而且统一,因为没有汗水;-) – janos

+0

谢谢你,但还有一个问题。我如何使用cat命令在bash脚本中使用shuf命令? – exsonic01