Search code examples
shellscriptingzsh

zsh - how to reference a variable that was dynamically named after multiple other variables?


Consider the following zsh script:

#! /bin/zsh

key1="a"
key2="b"

declare ${key1}_${key2}="c"

echo $a_b                       # this prints 'c' as expected
echo ${(P)${key1}_${key2}}      # Bad substitution

As you can see, I am confused about the syntax in the last line. How can I reference the variable a_b using the contents of $key1and $key2?

Also, would this work if a_b was an array, as in declare -a ${key1}_${key2}?


Solution

  • man zshexpn provides a list of 25(!) rules that govern how expansions are processed. The problem here is that ${key1}_$key2 isn't joined into a single word until step 23, while (P) is applied much earlier. You need a nested expansion to produce a single word upon which (P) can be applied. To do that, you can use the :- operator, which can omit a parameter name, expanding instead to whatever default value you provide.

    % print ${:-${key1}_$key2}
    a_b    
    

    Since nested substitutions are step 1 of the process, the above expression can fill in for the name expected by (P) in step 4.

    % print ${(P)${:-${key1}_$key2}}
    c