An interesting usage is when you call a bash function, you can use indirection on the parameters passed in. Then, you can nest calls to your indirection function in a nested manner using command substitution.
deref() { echo "${!1}"; }
aa="bb"
bb="cc"
cc="hello"
echo "$(deref aa)" # bb
echo "$(deref "$(deref aa)")" # cc
echo "$(deref "$(deref "$(deref aa)")")" # hello
Here's deref
used to solve the OP's problem:
deref() { echo "${!1}"; }
xab123="500"
yy="critical_ab123"
zz="$(deref "${yy//critical_/x}")"
echo "$zz" # Outputs: 500
Applied edits based on @charles-duffy comments:
- Disclaimer: reader beware, there are performance impacts to the command substitution used in this approach (FIFO creation, fork() of a subshell, read() and wait().
- Quotes were added to protect against lossy expansion, i.e.
echo "$zz"
is better than echo $zz
- Use POSIX-compliant function declaration syntax, i.e. replaced
function deref { echo "${!1}" ; }
with deref() { echo "${!1}" ; }
- Corrected quoting issue for each quoting context