Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: msys Compiler: gcc Compilation CFLAGS: -march=nocona -msahf -mtune=generic -O2 -pipe -D_STATIC_BUILD uname output: MINGW64_NT-10.0-19045 Zack2021HPPavilion 3.4.10.x86_64 2024-02-10 08:39 UTC x86_64 Msys Machine Type: x86_64-pc-msys
Bash Version: 5.2 Patch Level: 26 Release Status: release Description: The man page's descriptions of ${var@K} and ${var@k}: K Produces a possibly-quoted version of the value of parameter, except that it prints the values of indexed and associative arrays as a sequence of quoted key-value pairs (see Arrays above). k Like the K transformation, but expands the keys and values of indexed and associative arrays to separate words after word splitting. In the section on Arrays, we see: When assigning to an associative array, the words in a compound assignment may be either assignment statements, for which the subscript is required, or a list of words that is interpreted as a sequence of alternating keys and values: name=( key1 value1 key2 value2 ...). These are treated identically to name=( [key1]=value1 [key2]=value2 ...). The first word in the list determines how the remaining words are interpreted; all assignments in a list must be of the same type. When using key/value pairs, the keys may not be missing or empty; a final missing value is treated like the empty string. The "${assoc[@]@k}" transformation doesn't leave the separate key/value words quoted. I'm not sure if the phrasing of the documentation implies that it would or not. As such, I would expect that $ declare -A assoc_2=( "${assoc_1[@]@k}" ) would create assoc_2 as a duplicate of assoc_1. However, we see that the entire expansion becomes the key for a single array element, with its value being the empty string. Repeat-By: $ declare -A assoc_1=( [key 0]='value 0' [key 1]='value 1' [key 2]='value 2' [key 3]='value 3' ) $ unset assoc_2 $ declare -A assoc_2 $ printf '|%s|\n' "${assoc_1[*]@k}" |key 2 value 2 key 3 value 3 key 0 value 0 key 1 value 1| # All one word. Makes sense. $ assoc_2=( "${assoc_1[*]@k}" ) $ declare -p assoc_2 declare -A assoc_2=(["key 2 value 2 key 3 value 3 key 0 value 0 key 1 value 1"]="" ) # Still makes sense. $ printf '|%s|\n' "${assoc_1[@]@k}" |key 2| |value 2| |key 3| |value 3| |key 0| |value 0| |key 1| |value 1| # Got expanded to separate words, like it's supposed to. $ assoc_2=( "${assoc_1[@]@k}" ) $ declare -p assoc_2 declare -A assoc_2=(["key 2 value 2 key 3 value 3 key 0 value 0 key 1 value 1"]="" ) # Here, it did not. If it were up to me, "${scalar@k}" wouldn't do anything different than "${scalar}" and "${assoc[@]@K}" would expand to separate, quoted words. $ scalar='some words' $ printf '|%s|\n' "${scalar@K}" |'some words'| $ printf '|%s|\n' "${scalar@k}" |'some words'| # This is inconsistent with what the @k parameter transformation does with an array. $ printf '|%s|\n' "${assoc_1[*]@K}" |"key 2" "value 2" "key 3" "value 3" "key 0" "value 0" "key 1" "value 1" | $ printf '|%s|\n' "${assoc_1[@]@K}" |"key 2" "value 2" "key 3" "value 3" "key 0" "value 0" "key 1" "value 1" | # Quoted [*] and [@] array expansions do things differently everywhere else I can think of.