0

我想在 case switch 中对匹配的行进行一些操作。而且因为字符串很长,我想使用 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 选择器中使用花括号?

4

3 回答 3

4

来自bash 手册

case
case 命令的语法是:

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

...
... 每个模式都经历波浪号扩展、参数扩展、命令替换和算术扩展。
...

这意味着没有对's pattern执行大括号扩展,因此无法在此处使用它。case

于 2019-06-16T09:03:43.707 回答
4

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

于 2019-06-16T11:02:07.647 回答
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.

于 2019-06-16T20:05:04.683 回答