# Is there a special variable containing a case statement match

If you write a Bash case statement, can you get the current match without explicitly assigning it to a variable ?

Consider

case $(some subshell command sequence) in one) stuff ;; *) stuff "$case_match";;
esac

I know that I can do the below but wanted to be more succinct.

case_match=$(some subshell command sequence) case "$case_match" in
...

Is there a special variable representing $case_match ? Following comment from @Hauke Laging another contrived example. You can do this: today=$(date '+%A')
case "$today" in *) echo "It's$today" ;;
esac

But it would be nice to do this - the question asked if this was possible (but it isn't):

case $(date '+%A') in *) echo "It's$case_match" ;;
esac

(where case_match is the golden variable that eludes us)

• @Hauke Laging - yes you can. I'll add a contrived example to the question to illustrate it. – starfry Nov 11 '14 at 15:20

You can with a bit of a hack, but you need to be sure you have an unset variable available. For example:

unset foo  # Make sure foo is unset, or at least set to the empty string
case ${foo:-$(date +%m)} in
1) echo "Jan" ;;
2) echo "Feb" ;;
# ...
11) echo "Nov" ;;
12) echo "Dec" ;;
esac

Here, foo is being used as a dummy variable solely to allow the default parameter expansion to produce the output of the command substition.

• Yes, I've used this technique before but it is a little brittle. I think as a solution for bash this is probably as good as it gets! – starfry Nov 13 '14 at 12:31

No.

With zsh -o extendedglob however you can do:

case $(cmd) in ((#m)*) printf '%s\n' "Match:$MATCH"
esac

(#m) is the globbing flag to enable $MATCH. It's more useful in things like${var//(#m)?/<$MATCH>}. Or: case$(cmd) in
((#b)(???)(*)) printf '%s\n' "First 3 chars: $match[1], rest:$match[2]"
esac

(#b) for enabling back-references.

Or (without needing extendedglob):

case ${output::=$(cmd)} in
(*) printf '%s\n' "Output: \$output"
esac