问题描述
给出一个元素数组(服务器),我该如何对数组进行混洗以获得一个随机的新数组?
Given an array of elements (servers), how do I shuffle the array to obtain a random new array ?
inarray=("serverA" "serverB" "serverC")
outarray=($(randomize_func ${inarray[@]})
echo ${outarray[@]}
serverB serverC serverA
有一个命令 shuf
( man页),但并非在每个Linux上都存在.
There is a command shuf
(man page) but it does not exist on every linux.
这是我第一次尝试发布问题自动解答,如果您有更好的解决方案,请发布.
推荐答案
这是另一个纯Bash解决方案:
This is another pure Bash solution:
#! /bin/bash
# Randomly permute the arguments and put them in array 'outarray'
function perm
{
outarray=( "$@" )
# The algorithm used is the Fisher-Yates Shuffle
# (https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle),
# also known as the Knuth Shuffle.
# Loop down through 'outarray', swapping the item at the current index
# with a random item chosen from the array up to (and including) that
# index
local idx rand_idx tmp
for ((idx=$#-1; idx>0 ; idx--)) ; do
rand_idx=$(( RANDOM % (idx+1) ))
# Swap if the randomly chosen item is not the current item
if (( rand_idx != idx )) ; then
tmp=${outarray[idx]}
outarray[idx]=${outarray[rand_idx]}
outarray[rand_idx]=$tmp
fi
done
}
inarray=( 'server A' 'server B' 'server C' )
# Declare 'outarray' for use by 'perm'
declare -a outarray
perm "${inarray[@]}"
# Display the contents of 'outarray'
declare -p outarray
它是 Shellcheck -clean,并已使用Bash 3和Bash 4进行了测试.
It's Shellcheck-clean, and tested with Bash 3 and Bash 4.
呼叫者从 outarray
获取结果,而不是将它们放入 outarray
,因为 outarray =($(perm ...))
不起作用,如果要改组的任何项目包含空格字符,并且如果项目包含glob元字符,它也可能会中断.没有很好的方法从Bash函数返回非平凡的值.
The caller gets the results from outarray
rather than putting them in outarray
because outarray=( $(perm ...) )
doesn't work if any of the items to be shuffled contain whitespace characters, and it may also break if items contain glob metacharacters. There is no nice way to return non-trivial values from Bash functions.
如果从另一个函数调用了 perm
,则在调用方中声明 outarray
(例如,使用 local -a outarray
)将避免创建(或破坏)的全局变量.
If perm
is called from another function then declaring outarray
in the caller (e.g. with local -a outarray
) will avoid creating (or clobbering) a global variable.
可以无条件地进行交换,从而安全地简化代码,但代价是它们之间进行了一些无意义的交换.
The code could safely be simplified by doing the swap unconditionally, at the cost of doing some pointless swaps of items with themselves.
这篇关于如何随机循环bash中的数组(随机播放)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!