Associative arrays in bash do not necessarily have their values or keys in
the same order even if the keys are identical. This is not a bug
(according to the people hanging at #bash),
the associative arrays are simply unordered... But, IMO, it is quite
contrary to what the programmer expects, because in most programming
languages the hash function is static, in bash don't count on it!
Try that for instance:
$ declare -A aa1 aa2
$ for s in test train; do for i in $(seq 0 10); do aa1[$s,$i]=value_of_$s,$i; done; done
$ for key in ${!aa1[@]}; do aa2[$key]=value_of_$key; done
$ echo ${!aa1[@]}
$ echo ${!aa2[@]}
Look carefully... surprise!
You can fix that by sorting the keys and iterating through them, here some code that does that:
# sort words. For instance
# $(sw "truc troc trac")
# returns trac troc truc
sw() {
echo "$1" | tr " " "\n" | sort | tr "\n" " "
}
# display the values of an associative array according to a static
# order of its keys
sa() {
eval keys=\${!$1[@]}
sorted_keys=$(sw "$keys")
echo $(for k in $sorted_keys; do eval echo \${$1[$k]}; done)
}
Now you can use
$ echo $(sa aa1)
$ echo $(sa aa2)
instead of
$ echo ${aa1[@]}
$ echo ${aa2[@]}
and see that the order is respected.
Try that for instance:
$ declare -A aa1 aa2
$ for s in test train; do for i in $(seq 0 10); do aa1[$s,$i]=value_of_$s,$i; done; done
$ for key in ${!aa1[@]}; do aa2[$key]=value_of_$key; done
$ echo ${!aa1[@]}
$ echo ${!aa2[@]}
Look carefully... surprise!
You can fix that by sorting the keys and iterating through them, here some code that does that:
# sort words. For instance
# $(sw "truc troc trac")
# returns trac troc truc
sw() {
echo "$1" | tr " " "\n" | sort | tr "\n" " "
}
# display the values of an associative array according to a static
# order of its keys
sa() {
eval keys=\${!$1[@]}
sorted_keys=$(sw "$keys")
echo $(for k in $sorted_keys; do eval echo \${$1[$k]}; done)
}
Now you can use
$ echo $(sa aa1)
$ echo $(sa aa2)
instead of
$ echo ${aa1[@]}
$ echo ${aa2[@]}
and see that the order is respected.