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

时间:2019-06-16 08:55:04

标签: bash case glob curly-braces brace-expansion

我想对大小写切换中的匹配行进行一些操作。而且因为字符串很长,所以我想使用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中的大小写选择器中使用花括号吗?

3 个答案:

答案 0 :(得分:4)

来自bash manual

  

案例
  case命令的语法为:

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

...
  ...每个 pattern 都经过波浪号扩展,参数扩展,命令替换和算术扩展。
  ...

这意味着brace expansion不会在case模式上执行,因此无法在此处使用它。

答案 1 :(得分:3)

由于大括号扩展不是以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|...)与任何一个子模式匹配。

答案 2 :(得分:1)

除了匹配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

此方法不依赖于任何非标准扩展名,例如extglob