我正在尝试随机选择一个数组的项目,然后更新它再次执行直到最后一组:
#! /bin/bash
A=({1..27})
T=${#A[@]} #number of items in the array
N=3 #number of items to be chosen
V=$(($T/$N)) #number of times to loop
echo ${A[@]} " >> ${#A[@]}"
for ((n=0;n<$V;n++)); do
A1=()
for I in `shuf --input-range=0-$(( ${#A[*]} - 1 )) | head -${N}`; do #random chooses N items random
S=`echo ${A[$I]}` #the chosen items
#echo $S
A1+=("$S|") #creates an array with the chosen items
A=("${A[@]/$S}") #deletes the the chosen items from array
done
echo ${A[@]} " >> ${#A[@]}"
echo ${A1[@]} " >> ${#A1[@]}"
done
我使用此代码获得的输出类型是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 >> 27
1 4 5 6 7 8 9 10 11 1 1 14 15 16 17 18 19 1 2 4 5 6 7 >> 27
20| 2| 3| >> 3
4 6 7 8 9 0 1 4 6 7 8 9 2 4 6 7 >> 27
1| | 5| >> 3
6 7 8 9 0 1 6 7 8 9 2 6 7 >> 27
| | 4| >> 3
7 8 9 0 1 7 8 9 2 7 >> 27
6| | | >> 3
7 8 9 0 1 7 8 9 7 >> 27
| | 2| >> 3
7 9 0 1 7 9 7 >> 27
8| | | >> 3
7 9 1 7 9 7 >> 27
| | 0| >> 3
7 9 1 7 9 7 >> 27
| | | >> 3
1 >> 27
9| 7| | >> 3
为什么它在开始时工作正常并最终失败的任何想法?
答案 0 :(得分:1)
你的脚本中有一些错误的东西,特别是你(想你)从数组中删除元素的方式。你没有删除任何元素,你只是用每个字段中的空字符串替换它们的值!。这就是为什么你的数组一直有27个元素,在第一次迭代之后,所有2
和3
都从每个字段中删除。这是一个更惯用的脚本:
#! /bin/bash
a=( {1..27} )
n=3 #number of items to be chosen
while ((${#a[@]}>=n)); do
a1=()
for ((i=0;i<n;++i)); do
# pick an index
x=$((RANDOM%${#a[@]}))
# append its value to array a1
a1+=( "${a[x]}" )
# unset it
unset 'a[x]'
# reconstruct array a (make it non-sparse again)
a=( "${a[@]}" )
done
# print array
printf 'a: %s >> %s\n' "${a[*]}" "${#a[@]}"
# print chosen elements
printf 'a1: %s >> %s\n' "${a1[*]}" "${#a1[@]}"
done
答案 1 :(得分:1)
可以对您的脚本进行一些改进:
"${a[@]}"
)。unset a[j]
。a=("${a[@]}")
重新构建数组。-n
生成计数结果。$(…)
。这会将脚本缩小为:
#!/bin/bash
t=27 #number of items in the array
n=3 #number of items to be chosen
a=( $(seq 1 "$t") )
a1=()
while (( ${#a[@]} >= n )); do
for j in $(shuf -n "$n" --input-range=0-$((${#a[@]}-1)) ); do # choose $n random items.
a1+=("${a[j]}") # append to an array the chosen items.
unset "a[j]" # deletes the the chosen items from array.
done
a=("${a[@]}") # re-build the array.
echo "a ${a[@]} >> ${#a[@]}"
echo "a1 ${a1[@]} >> ${#a1[@]}"
done
这将产生此输出:
a 1 2 3 5 6 7 8 9 10 11 12 14 15 16 18 19 20 21 22 23 24 25 26 27 >> 24
a1 17 13 4 >> 3
a 1 2 5 6 7 8 10 11 12 14 15 16 18 19 20 21 22 23 24 26 27 >> 21
a1 17 13 4 25 3 9 >> 6
a 1 2 5 6 7 8 10 11 14 15 16 18 21 22 23 24 26 27 >> 18
a1 17 13 4 25 3 9 12 20 19 >> 9
a 1 2 5 7 8 10 11 14 15 16 21 22 24 26 27 >> 15
a1 17 13 4 25 3 9 12 20 19 23 6 18 >> 12
a 2 7 8 10 11 14 15 16 22 24 26 27 >> 12
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 >> 15
a 2 8 10 14 15 22 24 26 27 >> 9
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 >> 18
a 2 10 14 24 26 27 >> 6
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 22 8 15 >> 21
a 14 26 27 >> 3
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 22 8 15 2 24 10 >> 24
a >> 0
a1 17 13 4 25 3 9 12 20 19 23 6 18 1 5 21 7 11 16 22 8 15 2 24 10 14 26 27 >> 27
但是同样的阵列a1可以用shuf一步构建:
#!/bin/bash
t=27 # number of items in the array
n=3 # number of items to be chosen
a1=( $(shuf --input-range=1-"$t") )
printf '%3s ' "${a1[@]}"; echo
将打印:
$ ./script.sh
15 23 1 9 24 2 21 11 12 10 19 25 27 13 5 26 4 7 14 3 22 20 17 18 16 6 8
或者,如果结果必须是每行$n
个元素:
#!/bin/bash
t=27 # number of items in the array
n=3 # number of items to be chosen
a1=( $(shuf --input-range=1-"$t") )
while ((i+n<=t)); do
printf '%3s ' "${a1[@]:i:n}"; echo
((i+=n))
done
印刷:
$ ./script.sh
7 19 16
4 20 26
11 23 2
13 6 15
22 12 25
18 14 10
21 8 9
5 24 27
1 3 17
看起来更简单的解决方案。