在 BASH shell 中打乱数组元素的简单方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5533569/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple method to shuffle the elements of an array in BASH shell?
提问by Dave
I can do this in PHP but am trying to work within the BASH shell. I need to take an array and then randomly shuffle the contents and dump that to somefile.txt.
我可以在 PHP 中做到这一点,但我正在尝试在 BASH shell 中工作。我需要获取一个数组,然后随机打乱内容并将其转储到somefile.txt.
So given array Heresmyarray, of elements a;b;c;d;e;f;it would produce an output file, output.txt, which would contain elements f;c;b;a;e;d;
因此,给定数组 Heresmyarray 的元素a;b;c;d;e;f;,它将生成一个输出文件output.txt,其中将包含元素f;c;b;a;e;d;
The elements need to retain the semicolon delimiter. I've seen a number of bash shell array operations but nothing that seems even close to this simple concept. Thanks for any help or suggestions!
元素需要保留分号分隔符。我已经看到了许多 bash shell 数组操作,但似乎没有什么与这个简单的概念相近的。感谢您的任何帮助或建议!
采纳答案by kurumi
If you just want to put them into a file (use redirection > )
如果您只想将它们放入文件中(使用重定向 > )
$ echo "a;b;c;d;e;f;" | sed -r 's/(.[^;]*;)/ /g' | tr " " "\n" | shuf | tr -d "\n"
d;a;e;f;b;c;
$ echo "a;b;c;d;e;f;" | sed -r 's/(.[^;]*;)/ /g' | tr " " "\n" | shuf | tr -d "\n" > output.txt
If you want to put the items in array
如果你想把项目放在数组中
$ array=( $(echo "a;b;c;d;e;f;" | sed -r 's/(.[^;]*;)/ /g' | tr " " "\n" | shuf | tr -d " " ) )
$ echo ${array[0]}
e;
$ echo ${array[1]}
d;
$ echo ${array[2]}
a;
If your data has &#abcde;
如果您的数据有 &#abcde;
$ echo "a;&#abcde;c;d;e;f;" | sed -r 's/(.[^;]*;)/ /g' | tr " " "\n" | shuf | tr -d "\n"
d;c;f;&#abcde;e;a;
$ echo "a;&#abcde;c;d;e;f;" | sed -r 's/(.[^;]*;)/ /g' | tr " " "\n" | shuf | tr -d "\n"
&#abcde;f;a;c;d;e;
回答by David McKinley
The accepted answer doesn't match the headline question too well, though the details in the question are a bit ambiguous. The question asks about how to shuffle elements of an array in BASH, and kurumi's answer shows a way to manipulate the contents of a string.
接受的答案与标题问题不太匹配,尽管问题中的细节有点含糊不清。该问题询问如何在 BASH 中对数组的元素进行 shuffle,kurumi 的回答显示了一种操作字符串内容的方法。
kurumi nonetheless makes good use of the 'shuf' command, while siegeX shows how to work with an array.
尽管如此,kurumi 还是很好地利用了 'shuf' 命令,而 siegeX 展示了如何使用数组。
Putting the two together yields an actual "simple method to shuffle the elements of an array in BASH shell":
将两者放在一起会产生一个实际的“在 BASH shell 中混洗数组元素的简单方法”:
$ myarray=( 'a;' 'b;' 'c;' 'd;' 'e;' 'f;' )
$ myarray=( $(shuf -e "${myarray[@]}") )
$ printf "%s" "${myarray[@]}"
d;b;e;a;c;f;
回答by SiegeX
From the BashFaq
来自BashFaq
This function shuffles the elements of an array in-place using the Knuth-Fisher-Yates shuffle algorithm.
此函数使用 Knuth-Fisher-Yates 混洗算法就地混洗数组的元素。
#!/bin/bash
shuffle() {
local i tmp size max rand
# $RANDOM % (i+1) is biased because of the limited range of $RANDOM
# Compensate by using a range which is a multiple of the array size.
size=${#array[*]}
max=$(( 32768 / size * size ))
for ((i=size-1; i>0; i--)); do
while (( (rand=$RANDOM) >= max )); do :; done
rand=$(( rand % (i+1) ))
tmp=${array[i]} array[i]=${array[rand]} array[rand]=$tmp
done
}
# Define the array named 'array'
array=( 'a;' 'b;' 'c;' 'd;' 'e;' 'f;' )
shuffle
printf "%s" "${array[@]}"
Output
输出
$ ./shuff_ar > somefile.txt
$ cat somefile.txt
b;c;e;f;d;a;

