如何随机循环bash中的数组(随机播放) [英] how to randomly loop over an array (shuffle) in bash

查看:98
本文介绍了如何随机循环bash中的数组(随机播放)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个元素数组(服务器),我该如何对数组进行混洗以获得一个随机的新数组?

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中的数组(随机播放)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆