【问题标题】:How to use random number in shell script? [duplicate]如何在 shell 脚本中使用随机数? [复制]
【发布时间】:2017-12-20 21:57:24
【问题描述】:

使用shell脚本,我希望生成五个文件,我希望在每个文件中放置50000~150000不同的随机数范围。我尝试了类似以下的方法,

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

但这不起作用....如何为每个文件生成随机数并打印出来?

【问题讨论】:

  • @Steve 不是重复的,因为范围要求:$RANDOM 生成范围 0 - 32767 中的数字,但这里需要更大的范围。
  • 如果你想在 bash 中做点什么,man bash 通常是一个不错的开始方式。手册页很长;搜索关键字,例如random...
  • 我认为应该改写问题以明确指出范围 >32767 要求。
  • 在上述循环中,$B 没有用于输出任何内容。

标签: shell random


【解决方案1】:

每次读取变量$RANDOM的值, 它会给你一个介于 0 和 2^15 - 1 之间的随机数, 那是 0 和 32767。所以这并没有给你足够的范围。 您可以使用两个 $RANDOM 作为 base-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 的实现有一个警告: 有一个循环可以重新滚动,以防值有偏差, 但理论上这可能会阻止函数终止。 在实践中,这极不可能,但值得一提。

【讨论】:

  • 扩展范围的好解决方案。结果是有偏差的,因此如果您想要完全均匀的分布,您将需要使用不同的构造。要了解原因,请考虑比 randrange 可以处理的最高数字小 1 的范围,(2^15-1) * 2^15 + (2^15-1)。使用该范围,恰好有两个 RANDOM 数字的一个组合导致每个输出数字大于 1,而 两个 组合导致 1(一个随机数等于 0,另一个等于 1,或两个数字等于 2^15-1),结果 1 的可能性是任何其他数字的两倍。
  • @l0b0 好电话,谢谢。我想我纠正了它,“次要”警告说,如果你真的运气不好,程序可能永远不会终止 =)
  • RANDOM 是一个 bash 扩展,它不是在 shell 脚本中获取随机数的通用解决方案。
【解决方案2】:

shuf 可能就是你想要的:

$ shuf -i 50000-150000 -n 1
148495

【讨论】:

  • 美观、简单、统一,没有汗水;-)
  • 谢谢,但还有一个问题。如何在带有 cat 命令的 bash 脚本中使用 shuf 命令?
猜你喜欢
  • 2012-01-09
  • 2023-03-13
  • 2023-01-11
  • 2018-09-24
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 2011-03-02
相关资源
最近更新 更多