Warum gibt die printf-Anweisung in dieser Schleife das Array in der falschen Reihenfolge aus?

Warum gibt die printf-Anweisung in dieser Schleife das Array in der falschen Reihenfolge aus?

Wenn ich den folgenden Code ausführe, scheint die Ausgabe der printf-Anweisung ein Array in der falschen Reihenfolge anzuzeigen. In der Deklarationsanweisung wird das Quellelement vor dem Ziel deklariert und in der Ausgabe ist es umgekehrt.

YELLOW=$'\e[93m'
declare -A OP=( [Description]="remote to destination" [Source]="/var/www" [Destination]="/foo/bar" [Log]="my.log" [Email]="me@here" );

NO_COLS=`tput cols`
COLS_PER_COL=$(($NO_COLS/3))
PRINT_FORMAT="%"$COLS_PER_COL"s%""s\n"

for i in "${!OP[@]}"; do
    printf $PRINT_FORMAT "$i :" " $YELLOW${OP[$i]}$ENDCOL"
done ;

Die Ausgabe sieht wie folgt aus:

         Description : remote to destination
         Destination : /foo/bar
              Source : /var/www
                 Log : my.log
               Email : me@here

Kann mir jemand sagen, was hier passiert? Oder wie ich die richtige Reihenfolge gemäß der Array-Deklaration erreichen kann?

Antwort1

Assoziative Arrays bashbehalten in (und in anderen Sprachen) die Reihenfolge der Elemente in der Deklaration nicht bei.

Sie können ein weiteres assoziatives Array hinzufügen, um die Deklarationsreihenfolge im Auge zu behalten:

YELLOW=$'\e[93m'
declare -A OP=( [Description]="remote to destination"
                [Source]="/var/www"
                [Destination]="/foo/bar"
                [Log]="my.log"
                [Email]="me@here" )

declare -A IP=( [1]="Description"
                [2]="Source"
                [3]="Destination"
                [4]="Log"
                [5]="Email" );

NO_COLS="$(tput cols)"
COLS_PER_COL="$((NO_COLS/3))"
PRINT_FORMAT="%${COLS_PER_COL}s%s\n"

for i in "${!IP[@]}"; do
  k=${IP[$i]}
  printf "$PRINT_FORMAT" "$k :" " $YELLOW${OP[$k]}$ENDCOL"
done

verwandte Informationen