10

My question is the zsh equivalent of the question asked here: How can I use a variable as a case condition? I would like to use a variable for the condition of a case statement in zsh. For example:

input="foo"
pattern="(foo|bar)"

case $input in
$pattern)
    echo "you sent foo or bar"
;;
*)
    echo "foo or bar was not sent"
;;
esac

I would like to use the strings foo or bar and have the above code execute the pattern case condition.

1 Answer 1

13

With this code saved to the file first,

pattern=fo*
input=foo
case $input in
$pattern)
   print T
   ;;
fo*)
   print NIL
   ;;
esac

under -x we may observe that the variable appears as a quoted value while the raw expression does not:

% zsh -x first
+first:1> pattern='fo*'
+first:2> input=foo
+first:3> case foo (fo\*)
+first:3> case foo (fo*)
+first:8> print NIL
NIL

That is, the variable is being treated as a literal string. If one spends enough time in zshexpn(1) one might be aware of the glob substitution flag

   ${~spec}
          Turn on the GLOB_SUBST option for the evaluation of spec; if the
          `~'  is  doubled,  turn  it  off.   When this option is set, the
          string resulting from the expansion will  be  interpreted  as  a
          pattern anywhere that is possible,

so if we modify $pattern to use that

pattern=fo*
input=foo
case $input in
$~pattern)                # !
   print T
   ;;
fo*)
   print NIL
   ;;
esac

we see instead

% zsh -x second
+second:1> pattern='fo*'
+second:2> input=foo
+second:3> case foo (fo*)
+second:5> print T
T

for your case the pattern must be quoted:

pattern='(foo|bar)'
input=foo
case $input in
$~pattern)
   print T
   ;;
*)
   print NIL
   ;;
esac

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .