bash 切换案例与失败?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5562253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:22:05  来源:igfitidea点击:

Switch case with fallthrough?

bashswitch-statement

提问by Mischka

I am looking for the correct syntax of the switch statement with fallthrough cases in Bash (ideally case-insensitive). In PHP I would program it like:

我正在寻找在 Bash 中包含失败案例的 switch 语句的正确语法(最好不区分大小写)。在 PHP 中,我会这样编程:

switch($c) {
    case 1:
        do_this();
        break;
     case 2:
     case 3:
        do_what_you_are_supposed_to_do();
        break;
     default:
        do_nothing(); 
}

I want the same in Bash:

我希望在 Bash 中也一样:

case "$C" in
    "1")
        do_this()
        ;;
    "2")
    "3")
        do_what_you_are_supposed_to_do()
        ;;
    *)
        do_nothing();
        ;; 
esac

This somehow doesn't work: function do_what_you_are_supposed_to_do()should be fired when $C is 2 OR 3.

这在某种程度上不起作用:do_what_you_are_supposed_to_do()当 $C 是 2 或 3 时应该触发函数。

回答by geekosaur

Use a vertical bar (|) for "or".

使用竖线 ( |) 表示“或”。

case "$C" in
"1")
    do_this()
    ;;
"2" | "3")
    do_what_you_are_supposed_to_do()
    ;;
*)
    do_nothing()
    ;;
esac

回答by Jasen

Recent bashversions allow fall-through by using ;&in stead of ;;: they also allow resuming the case checks by using ;;&there.

最近的bash版本允许通过使用;&in 而不是;;: 他们还允许通过使用;;&那里来恢复案例检查。

for n in 4 14 24 34
do
  echo -n "$n = "
  case "$n" in
   3? )
     echo -n thirty-
     ;;&   #resume (to find ?4 later )
   "24" )
     echo -n twenty-
     ;&   #fallthru
   "4" | [13]4)
     echo -n four 
     ;;&  # resume ( to find teen where needed )
   "14" )
     echo -n teen
  esac
  echo 
done

sample output

样本输出

4 = four
14 = fourteen
24 = twenty-four
34 = thirty-four

回答by Sprinterfreak

  • Do not use ()behind function names in bash unless you like to define them.
  • use [23]in case to match 2or 3
  • static string cases should be enclosed by ''instead of ""
  • ()除非您想定义它们,否则不要在 bash 中使用后面的函数名称。
  • 用于[23]匹配23
  • 静态字符串案例应该用''而不是""

If enclosed in "", the interpreter (needlessly) tries to expand possible variables in the value before matching.

如果包含在 中"",解释器(不必要地)会在匹配之前尝试扩展值中可能的变量。

case "$C" in
'1')
    do_this
    ;;
[23])
    do_what_you_are_supposed_to_do
    ;;
*)
    do_nothing
    ;;
esac

For case insensitive matching, you can use character classes (like [23]):

对于不区分大小写的匹配,您可以使用字符类(如[23]):

case "$C" in

# will match C='Abra' and C='abra'
[Aa]'bra')
    do_mysterious_things
    ;;

# will match all letter cases at any char like `abra`, `ABRA` or `AbRa`
[Aa][Bb][Rr][Aa])
    do_wild_mysterious_things
    ;;

esac

But abradidn't hit anytime because it will be matched by the first case.

但是abra任何时候都没有命中,因为它会被第一种情况匹配。

If needed, you can omit ;;in the first case to continue testing for matches in following cases too. (;;jumps to esac)

如果需要,您可以;;在第一种情况下省略以在以下情况下继续测试匹配项。(;;跳到esac

回答by René Steetskamp

Try this:

尝试这个:

case $VAR in
normal)
    echo "This doesn't do fallthrough"
    ;;
special)
    echo -n "This does "
    ;&
fallthrough)
    echo "fall-through"
    ;;
esac

回答by rashok

If the values are integer then you can use [2-3]or you can use [5,7,8]for non continuous values.

如果值是整数,那么您可以使用[2-3]或者您可以使用[5,7,8]非连续值。

#!/bin/bash
while [ $# -gt 0 ];
do
    case  in
    1)
        echo "one"
        ;;
    [2-3])
        echo "two or three"
        ;;
    [4-6])
        echo "four to six"
        ;;
    [7,9])
        echo "seven or nine"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done

If the values are string then you can use |.

如果值是字符串,那么您可以使用|.

#!/bin/bash
while [ $# -gt 0 ];
do
    case  in
    "one")
        echo "one"
        ;;
    "two" | "three")
        echo "two or three"
        ;;
    *)
        echo "others"
        ;;
    esac
    shift
done