【问题标题】:Pick and print one of three strings at random in Bash script在 Bash 脚本中随机选择并打印三个字符串之一
【发布时间】:2023-03-26 09:43:01
【问题描述】:

如何打印一个值,1、2 或 3(随机)。我最好的猜测失败了:

#!/bin/bash

1 = "2 million"
2 = "1 million"
3 = "3 million"

print randomint(1,2,3)

【问题讨论】:

  • 最小的问题是:从{1, 2, 3}中选择一个整数
  • stackoverflow.com/questions/2556190/… + arrays 解决了这个问题。
  • 那些1 = "2 million" 行应该是什么意思?它们不是有效的 bash 构造。

标签: bash shell random


【解决方案1】:

Coreutils shuf

Coreutils 中出现,如果字符串不包含换行符,此函数运行良好。

例如从abc中随机选择一个字母:

printf 'a\nb\nc\n' | shuf -n1

POSIX eval 数组模拟 + RANDOM

修改 Marty 的 eval 技术以模拟数组(非 POSIX):

a1=a
a2=b
a3=c
eval echo \$$(expr $RANDOM % 3 + 1)

这仍然留下了 RANDOM 非 POSIX。

awkrand() 是一种 POSIX 方式来解决这个问题。

【讨论】:

  • 什么是“shuf”; linux?我在 mac osx 上看不到它,而且数组非常难看。看下面的答案
  • @MartyMcGowan GNU 非 POSIX 已链接。同意数组很难看,但是 shuf 的第一个选项不使用数组。同意更大的便携性会很酷。我不知道set 可以按照您的建议设置参数,这很有趣。
【解决方案2】:

想要使用来自 coreutils 的 shuf 使用漂亮的 -n1 -e 方法来证实。

示例用法,在值abc 中随机选择:

CHOICE=$(shuf -n1 -e a b c)
echo "choice: $CHOICE"

我查看了两个样本大小(1000 和 10000)的天平:

$ for lol in $(seq 1000); do shuf -n1 -e a b c; done > shufdata
$ less shufdata | sort | uniq -c
    350 a
    316 b
    334 c
$ for lol in $(seq 10000); do shuf -n1 -e a b c; done > shufdata
$ less shufdata | sort | uniq -c
   3315 a
   3377 b
   3308 c

参考:https://www.gnu.org/software/coreutils/manual/html_node/shuf-invocation.html

【讨论】:

    【解决方案3】:

    64 个字符的字母数字字符串

    randomString32() {
        index=0
        str=""
    
        for i in {a..z}; do arr[index]=$i; index=`expr ${index} + 1`; done
        for i in {A..Z}; do arr[index]=$i; index=`expr ${index} + 1`; done
        for i in {0..9}; do arr[index]=$i; index=`expr ${index} + 1`; done
        for i in {1..64}; do str="$str${arr[$RANDOM%$index]}"; done
    
        echo $str
    }
    

    【讨论】:

    • 我相信这并不能回答这个问题:OP 想要从 3 个字符串中挑选一个,而不是生成一个完全随机的字符串。而/dev/random 则更好。
    【解决方案4】:
    ~.$ set -- "First Expression" Second "and Last"
    ~.$ eval echo \$$(expr $RANDOM % 3 + 1)
    and Last
    ~.$ 
    

    【讨论】:

      【解决方案5】:

      要使用 bash 生成随机数,请使用 $RANDOM 内部 Bash 函数:

      arr[0]="2 million"
      arr[1]="1 million"
      arr[2]="3 million"
      
      rand=$[ $RANDOM % 3 ]
      echo ${arr[$rand]}
      

      来自 RANDOM 的 bash 手册:

      每次这个参数 引用,0之间的随机整数 并生成 32767。序列 随机数可以被初始化 通过为 RANDOM 赋值。如果 RANDOM 未设置,它失去了它的 特殊属性,即使是 随后重置。

      【讨论】:

      • $[ ] 是支持 1970 年代 Bourne 语法的兼容性构造;该构造在最近的标准中没有,因此不能保证被 bash 以外的更现代的 shell 支持(历史上包含它)。自 1991 年发布 POSIX sh 以来,standardized 数学构造一直是 $(( )),所以这应该是 rand=$(( RANDOM % 3 ))
      • 我还建议引用 -- 如echo "${arr[$rand]}";这样我们就不会在 IFS 中使用不同的值或使用扩展为 glob 的数组值时出现意外行为。 (例如,如果IFS=0123456789,那么echo ${arr[$rand} 不带引号根本不会打印任何数字)。
      • 如何让 rand=$[ $RANDOM % ${#arr[@]} ] 避免硬编码 3?
      猜你喜欢
      • 1970-01-01
      • 2018-04-22
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2012-02-03
      • 2017-12-03
      • 1970-01-01
      相关资源
      最近更新 更多