Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use patterns in a case statement?

The man page says that case statements use "filename expansion pattern matching".
I usually want to have short names for some parameters, so I go:

case $1 in     req|reqs|requirements) TASK="Functional Requirements";;     met|meet|meetings) TASK="Meetings with the client";; esac  logTimeSpentIn "$TASK" 

I tried patterns like req* or me{e,}t which I understand would expand correctly to match those values in the context of filename expansion, but it doesn't work.

like image 783
Ramiro Rela Avatar asked Dec 29 '10 13:12

Ramiro Rela


People also ask

What does Esac mean in shell script?

esac statement is to give an expression to evaluate and to execute several different statements based on the value of the expression. The interpreter checks each case against the value of the expression until a match is found. If nothing matches, a default condition will be used.

What do you use in a case statement to tell bash that you're done with a specific test?

Each case statement in bash starts with the 'case' keyword, followed by the case expression and 'in' keyword. The case statement is closed by 'esac' keyword. We can apply multiple patterns separated by | operator. The ) operator indicates the termination of a pattern list.

Which command ends a case statement?

A case statement must start with the case keyword and end with the esac keyword. The expression is evaluated and compared with the patterns in each clause until a match is found. The statement or statements in the matching clause are executed. A double semicolon “ ;; ” is used to terminate a clause.

How do bash case statements work?

The case statement starts with the case keyword followed by the $variable and the in keyword. The statement ends with the case keyword backwards - esac . The script compares the input $variable against the patterns in each clause until it finds a match.


2 Answers

Brace expansion doesn't work, but *, ? and [] do. If you set shopt -s extglob then you can also use extended pattern matching:

  • ?() - zero or one occurrences of pattern
  • *() - zero or more occurrences of pattern
  • +() - one or more occurrences of pattern
  • @() - one occurrence of pattern
  • !() - anything except the pattern

Here's an example:

shopt -s extglob for arg in apple be cd meet o mississippi do     # call functions based on arguments     case "$arg" in         a*             ) foo;;    # matches anything starting with "a"         b?             ) bar;;    # matches any two-character string starting with "b"         c[de]          ) baz;;    # matches "cd" or "ce"         me?(e)t        ) qux;;    # matches "met" or "meet"         @(a|e|i|o|u)   ) fuzz;;   # matches one vowel         m+(iss)?(ippi) ) fizz;;   # matches "miss" or "mississippi" or others         *              ) bazinga;; # catchall, matches anything not matched above     esac done 
like image 184
Dennis Williamson Avatar answered Sep 21 '22 21:09

Dennis Williamson


I don't think you can use braces.

According to the Bash manual about case in Conditional Constructs.

Each pattern undergoes tilde expansion, parameter expansion, command substitution, and arithmetic expansion.

Nothing about Brace Expansion unfortunately.

So you'd have to do something like this:

case $1 in     req*)         ...         ;;     met*|meet*)         ...         ;;     *)         # You should have a default one too. esac 
like image 27
plundra Avatar answered Sep 20 '22 21:09

plundra