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

Dav*_*ave 10 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数组操作,但似乎没有什么比这个简单的概念更接近.感谢您的任何帮助或建议!

Dav*_*ley 16

接受的答案与标题问题不太匹配,尽管问题中的细节有点含糊不清.这个问题询问如何在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;
Run Code Online (Sandbox Code Playgroud)

  • `shuf` 命令使用空格作为分隔符,因此会分解任何包含空格的数组元素。 (3认同)
  • 我有与此线程中所述完全相同的问题,这个答案有效并且最简洁。 (2认同)

Sie*_*geX 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[@]}"
Run Code Online (Sandbox Code Playgroud)

产量

$ ./shuff_ar > somefile.txt
$ cat somefile.txt
b;c;e;f;d;a;
Run Code Online (Sandbox Code Playgroud)


kur*_*umi 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
Run Code Online (Sandbox Code Playgroud)

如果要将项目放在数组中

$ 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;
Run Code Online (Sandbox Code Playgroud)

如果您的数据有 &#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;
Run Code Online (Sandbox Code Playgroud)