在BASH shell中混洗数组元素的简单方法?

时间:2011-04-04 00:41:20

标签: bash shell shuffle

我可以在PHP中执行此操作,但我尝试在BASH shell中工作。我需要获取一个数组,然后随机随机播放内容并将其转储到somefile.txt

所以给定数组Heresmyarray,元素a;b;c;d;e;f;它会生成一个输出文件output.txt,其中包含元素f;c;b;a;e;d;

元素需要保留分号分隔符。我已经看过很多bash shell数组操作,但似乎没有什么比这个简单的概念更接近。感谢您提供任何帮助或建议!

3 个答案:

答案 0 :(得分:12)

接受的答案与标题问题不太匹配,尽管问题中的细节有点含糊不清。这个问题询问如何在BASH中混淆数组的元素,而kurumi的答案显示了一种操作字符串内容的方法。

尽管如此,kurumi仍然充分利用了'shuf'命令,而siegeX则展示了如何使用数组。

将两者放在一起产生一个实际的“简单方法来在BASH shell中混洗数组的元素”:

$ myarray=( 'a;' 'b;' 'c;' 'd;' 'e;' 'f;' )
$ myarray=( $(shuf -e "${myarray[@]}") )
$ printf "%s" "${myarray[@]}"
d;b;e;a;c;f;

答案 1 :(得分:9)

来自BashFaq

  

此函数使用Knuth-Fisher-Yates shuffle算法就地对阵列的元素进行混洗。

#!/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[@]}"

输出

$ ./shuff_ar > somefile.txt
$ cat somefile.txt
b;c;e;f;d;a;

答案 2 :(得分:8)

如果您只想将它​​们放入文件中(使用重定向>)

$ echo "a;b;c;d;e;f;" | sed -r 's/(.[^;]*;)/ \1 /g' | tr " " "\n" | shuf | tr -d "\n"
  d;a;e;f;b;c;

$ echo "a;b;c;d;e;f;" | sed -r 's/(.[^;]*;)/ \1 /g' | tr " " "\n" | shuf | tr -d "\n" > output.txt

如果要将项目放在数组中

$ array=( $(echo "a;b;c;d;e;f;" | sed -r 's/(.[^;]*;)/ \1 /g' | tr " " "\n" | shuf | tr -d " " ) )
$ echo ${array[0]}
e;
$ echo ${array[1]}
d;
$ echo ${array[2]}
a;

如果您的数据有&#abcde;

$ echo "a;&#abcde;c;d;e;f;" | sed -r 's/(.[^;]*;)/ \1 /g' | tr " " "\n" | shuf | tr -d "\n"
d;c;f;&#abcde;e;a;
$ echo "a;&#abcde;c;d;e;f;" | sed -r 's/(.[^;]*;)/ \1 /g' | tr " " "\n" | shuf | tr -d "\n"
&#abcde;f;a;c;d;e;