As already pointed out, there is no mistake. Associative arrays are stored in a 'hash' order. If you want ordering, you don't use associative arrays. Or, you use a non-associative array as well as an associative array.
Keep a second (non-associative) array that identifies the keys in the order that they're created. Then step through the second array, using its contents to key the first (associative) array when printing the data. Like this:
declare -A groups; declare -a orders;
groups["group1"]="123"; orders+=( "group1" )
groups["group2"]="456"; orders+=( "group2" )
groups["group3"]="789"; orders+=( "group3" )
groups["group4"]="abc"; orders+=( "group4" )
groups["group5"]="def"; orders+=( "group5" )
# Convoluted option 1
for i in "${!orders[@]}"
do
echo "${orders[$i]}: ${groups[${orders[$i]}]}"
done
echo
# Convoluted option 1 - 'explained'
for i in "${!orders[@]}"
do
echo "$i: ${orders[$i]}: ${groups[${orders[$i]}]}"
done
echo
# Simpler option 2 - thanks, PesaThe
for i in "${orders[@]}"
do
echo "$i: ${groups[$i]}"
done
The 'simpler option 2' was suggested by PesaThe in a comment, and should be used in preference to the 'convoluted option'.
Sample output:
group1: 123
group2: 456
group3: 789
group4: abc
group5: def
0: group1: 123
1: group2: 456
2: group3: 789
3: group4: abc
4: group5: def
group1: 123
group2: 456
group3: 789
group4: abc
group5: def
You probably don't want to have two statements per line like that, but it emphasizes the parallelism between the handling of the two arrays.
The semicolons after the assignments in the question are not really necessary (though they do no active harm, beyond leaving the reader wondering 'why?').
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…