从数组中选择一个随机项

51 arrays random shell

我在Shell脚本中创建一个bot:

# Array with expressions
expressions=("Ploink Poink" "I Need Oil" "Some Bytes are Missing!" "Poink Poink" "Piiiip Beeeep!!" "Hello" "Whoops! I'm out of memmory!")

# Seed random generator
RANDOM=$$$(date +%s)

# Loop loop loop loop loop loop ...
while [ 1 ]
do
    # Get random expression...
    selectedexpression=${expressions[$RANDOM % ${#RANDOM[*]}]}

    # Write to Shell
    echo $selectedexpression


    # Wait an half hour
    sleep 1 # It's one second for debugging, dear SOers
done
Run Code Online (Sandbox Code Playgroud)

我希望它从expressions每秒打印一个随机项目.我试过这个,但它不起作用.它每次只打印第一个(Ploink Poink).谁能帮我吗?谢谢

Jac*_*son 83

将您定义的行更改selectedexpression

selectedexpression=${expressions[$RANDOM % ${#expressions[@]} ]}

您希望索引成为expression从0到expression数组长度的随机数.这样做会.

  • 真正.但是,除非您的表达式列表很长,否则效果很小.$ RANDOM是介于0和32767之间的数字.假设您的列表中有100个项目.前67个项目的机会为328/32767(.01001),而最后33个项目的机会为327/32767(.00998).对于较短的列表,差异甚至更小.不过,你提出了一个很好的观点,shell RANDOM函数不适合你必须拥有真正随机数的情况,例如加密. (12认同)
  • 请注意,该代码仍将偏向较低的数组索引. (7认同)
  • 对于得到这个答案的任何人,并将其应用于ZSH:ZSH中的数组索引从1开始(由于某种原因),因此将语句更改为:`selectedexpression = $ {expressions [$(($ RANDOM%$ {#expressions [@]} + 1))]}` (5认同)

noo*_*nja 18

arr[0]="Ploink Poink"
arr[1]="I Need Oil"
arr[2]="Some Bytes are Missing!"
arr[3]="Poink Poink"
arr[4]="Piiiip Beeeep!!"
arr[5]="Hello"
arr[6]="Whoops! I'm out of memmory!"
rand=$[$RANDOM % ${#arr[@]}]
echo $(date)
echo ${arr[$rand]}
Run Code Online (Sandbox Code Playgroud)


pre*_*to8 6

使用 shuf 的解决方案:

expressions=("Ploink Poink" "I Need Oil" "Some Bytes are Missing!" "Poink Poink" "Piiiip Beeeep!!" "Hello" "Whoops! I'm out of memmory!")
selectedexpression=$(printf "%s\n" "${expressions[@]}" | shuf -n1)
echo $selectedexpression
Run Code Online (Sandbox Code Playgroud)

或者可能更好:

select_random() {
    printf "%s\0" "$@" | shuf -z -n1 | tr -d '\0'
}

expressions=("Ploink Poink" "I Need Oil" "Some Bytes are Missing!" "Poink Poink" "Piiiip Beeeep!!" "Hello" "Whoops! I'm out of memmory!")
selectedexpression=$(select_random "${expressions[@]}")
echo "$selectedexpression"
Run Code Online (Sandbox Code Playgroud)


Pow*_*ers 5

这是另一个可能比 Jacob Mattison 的解决方案更随机的解决方案(从jot联机帮助页很难说):

declare -a expressions=('Ploink' 'I Need Oil' 'Some Bytes are Missing' 'Poink Poink' 'Piiiip Beeeep' 'Hello' 'Whoops I am out of memory')
index=$( jot -r 1  0 $((${#expressions[@]} - 1)) )
selected_expression=${expressions[index]}
Run Code Online (Sandbox Code Playgroud)