是否可以在 bash 中的 case 选择器中使用花括号?

Is it possible to use curly braces in case selector in bash?

我想对大小写切换中的匹配行进行一些操作。因为字符串很长,所以我想使用 bash 大括号。但是没用。

这段没有花括号的代码按预期工作:

for i in longstr_one longstr_two; do
    case $i in
    longstr_one| longstr_five)
        echo matched $i
        ;;
        *)
        echo no matches of $i
        ;;
    esac
done

我得到了预期的结果:

matched longstr_one
no matches of longstr_two

但是下面带花括号的代码不会:

for i in longstr_one longstr_two; do
    case $i in
    longstr_{one|,five})
        echo matched $i
        ;;
        *)
        echo no matches of $i
        ;;
    esac
done   

我得到了错误的结果:

no matches of longstr_one
no matches of longstr_two

为什么不起作用? 是否可以在 bash?

中的 case 选择器中使用花括号

来自bash manual

case
The syntax of the case command is:

case word in
      [ [(] pattern [| pattern]…) command-list ;;]…
esac

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

也就是说brace expansion没有在casepattern上执行,所以不能在这里使用。

由于 case 模式中没有进行大括号扩展,您可以改用 bash 的扩展 glob 语法:

shopt -s extglob

for i in longstr_one longstr_two; do
    case $i in
    longstr_@(one|five) )
        echo "matched $i"
        ;;
        *)
        echo "no matches of $i"
        ;;
    esac
done

语法 @(this|that|theother|...) 匹配任一子模式。

不匹配 i 的整个值,只匹配删除公共前缀后剩余的部分。

for i in longstr_one longstr_two; do
    case ${i#longstr_} in
    one|five)
        echo matched $i
        ;;
        *)
        echo no matches of $i
        ;;
    esac
done

此方法不依赖于任何 non-standard 扩展,例如 extglob