Hi in my previous question I got clarity on how to use associative arrays in zsh shell.

But whenever I trigger the following command in my script

for KEY in ${!array[@]} to iterate amongst the keys in my array

I get a bad substitution error.

even echo ${!array[@]} gives the same.

NB: array is the name of my associative array

3 Answers 3


zsh has different parameter substitution than Bash, which is documented in man zshexpn. It supports a variety of modifiers to expansion behaviour, which are put in parentheses before the variable name: ${(X)name}. The modifier to include array keys (including for associative arrays) is k: ${(k)array} expands to the list of keys in the array, except that if a key is the empty string, it is omitted. Use double quotes and the @ modifier to retain the empty key.

for x in "${(@k)array}" ; ...

will loop over the keys of the array array.

  • 1
    ${(k)array} expands to the non-empty keys. Use "${(k@)array}" if there may be empty keys. Aug 13, 2014 at 10:31

You must use "${(@k)array}", "${(k)array}" only expands to the non-empty keys:

typeset -A array
array=(k1 v1 k2 v2 k3 v3)

for k in "${(@k)array}"; do
  printf "%s -> %s\n" "$k" "$array[$k]"


$ zsh test.zsh 
k1 -> v1
k2 -> v2
k3 -> v3

You can also replace for loop with key, value expansion:

printf '%s -> %s\n' "${(@kv)array}"

AFAIK, ${!...} doesn't exist. I suppose you want: ${(k)array[@]}, or simply ${(k)array}. For more information, see the zshexpn(1) man page, which says for the k expansion flag: "If name refers to an associative array, substitute the keys (element names) rather than the values of the elements."

  • what is AFAIK? sorry for my ignorance. Aug 13, 2014 at 10:11
  • as far as I know
    – vinc17
    Aug 13, 2014 at 10:15
  • 1
    ${(k)array} expands to the non-empty keys. Use "${(k@)array}" if there may be empty keys. Aug 13, 2014 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.