特定のシーケンスを尊重し、他の配列と組み合わせた新しい配列を作成しようとしています。純粋なバッシュで。例:
numbers=(0 1 2 3 4 5 6 7 8);
colors=(red blue green);
loop_sequence=(numbers numbers colors numbers colors colors)
出力例:
0 1 red 2 blue green 3 4 red 5 blue green 6 7 red 8 blue green 0 1 red 2 blue green...
しかし、繰り返しの内部ループを作成するのは難しいことを知っています。どんな助けでも大歓迎です。
答え1
Bash では動的変数名がトリッキーですが、変数を介して間接的に名前を付けることができます。
numbers=(0 1 2 3 4 5 6 7 8)
colors=(red blue green)
loop_sequence=(numbers numbers colors numbers colors colors)
# keep track of where you are in each array
declare -A idx=([numbers]=0 [colors]=0)
for varname in "${loop_sequence[@]}"; do
tmp="${varname}[${idx[$varname]}]" # construct the array reference
echo "$varname => ${!tmp}" # variable indirection gets the value
(( idx[$varname]++ ))
done
出力
numbers => 0
numbers => 1
colors => red
numbers => 2
colors => blue
colors => green
loop_sequenceを無期限に繰り返すには、次のようにします。
declare -A idx=([numbers]=0 [colors]=0)
# store the array sizes for convenience
declare -A size=([numbers]=${#numbers[@]} [colors]=${#colors[@]})
while true; do
for varname in "${loop_sequence[@]}"; do
tmp="${varname}[${idx[$varname]}]"
echo "$varname => ${!tmp}"
# loop the array index
(( idx[$varname] = (idx[$varname]+1) % size[$varname] ))
done
done | less
答え2
x=$(( (l=${#loop_sequence[@]}) * (n=${#numbers[@]}) * (c=${#colors[@]})))
_n= _c= _l=
set --
math(){ return "$(($1-=-($1<${1#?})|$1-1))"; }
while [ "$((x-=1))" -ge 0 ]
do math _l
case "${loop_sequence[$?-1]}" in
n*) math _n
set -- "$@" "${numbers[$?-1]}";;
*) math _c
set -- "$@" "${colors[$?-1]}";;
esac
done; printf %s\\n "$@"
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green
0
1
red
2
blue
green
3
4
red
5
blue
green
6
7
red
8
blue
green