如何在 case 语句中使用模式?

问题描述 投票:0回答:3

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
这样的模式,我知道这些模式可以正确扩展以匹配文件名扩展上下文中的这些值,但它不起作用。

bash case-statement
3个回答
208
投票

大括号扩展不起作用,但

*
?
[]
起作用。如果您设置了
shopt -s extglob
,那么您还可以使用扩展模式匹配

  • ?()
    - 模式出现零次或一次
  • *()
    - 零次或多次出现模式
  • +()
    - 出现一次或多次模式
  • @()
    - 模式出现一次
  • !()
    - 除了图案之外的任何东西

这是一个例子:

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

49
投票

我认为你不能使用牙套。

根据 Bash 手册关于Conditional Constructs中的情况。

每个模式都有波形符 扩展、参数扩展、 命令替换和算术 扩展。

不幸的是,没有关于支架扩展的信息。

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

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

10
投票

if
grep -Eq

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

地点:

  • -q
    阻止
    grep
    产生输出,它只产生退出状态
  • -E
    启用扩展正则表达式

我喜欢这个因为:

一个缺点是这可能比

case
慢,因为它调用外部
grep
程序,但在使用 Bash 时我倾向于最后考虑性能。

case
是 POSIX 7

Bash 默认情况下遵循 POSIX,没有

shopt
,如 https://stackoverflow.com/a/4555979/895245

所述

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

条件构造案例应执行与多个模式中的第一个相对应的复合列表(请参阅模式匹配符号)[...]具有相同复合列表的多个模式应由“|”分隔象征。 [...]

案例结构的格式如下:

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.模式匹配符号”仅提到

?
*
[]

© www.soinside.com 2019 - 2024. All rights reserved.