如何在bash脚本的case语句中使用模式?

man页说, case语句使用“文件名扩展模式匹配”。
我通常希望有一些参数的短名称,所以我去:

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

我尝试了req*me{e,}t这样的模式,我知道它会正确扩展,以便在文件名扩展的上下文中匹配这些值,但不起作用。

Brace扩展不起作用,但* ,? 和[]做。 如果您设置shopt -s extglob那么您也可以使用扩展模式匹配 :

  • ?() – 模式的零次或一次出现
  • *() – 零次或多次出现的模式
  • +() – 一个或多个模式
  • @() – 模式的一个发生
  • !() – 除了模式之外的任何东西

这是一个例子:

 case $1 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 esac 

我不认为你可以使用大括号。

根据Bash有关条件构造的案例手册。

每个模式经历代数扩展,参数扩展,命令replace和算术扩展。

不幸的是Brace扩展没有什么。

所以你必须做这样的事情:

 case $1 in req*) ... ;; met*|meet*) ... ;; *) # You should have a default one too. esac 

ifgrep -E更便携的解决scheme

为了便于携带,我build议你只使用if语句和支持扩展正则expression式的 grep -E ,例如:

 arg='abc' if echo "$arg" | grep -Eq 'ac|d.*'; then echo 'first' elif echo "$arg" | grep -Eq 'a{2,3}'; then echo 'second' fi 

POSIX 7

Bash似乎遵循POSIX默认情况下没有shopt所提到的https://stackoverflow.com/a/4555979/895245

以下是引用: http : //pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01 “案例条件构build”部分:

条件构造的情况下应该执行对应于多个模式中第一个模式的复合列表(参见模式匹配符号)[…]具有相同复合列表的多个模式将由“|”分隔。 符号。 […]

案例结构的格式如下:

 case word in [(] pattern1 ) compound-list ;; [[(] pattern[ | pattern] ... ) compound-list ;;] ... [[(] pattern[ | pattern] ... ) compound-list] esac 

然后http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13部分“2.13。模式匹配符号”仅提及;?*[]