切换到失败状态?


193

我正在使用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(); 
}

我想要在Bash中也一样:

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

这种方式不起作用:do_what_you_are_supposed_to_do()$ C为2或3时应触发函数。


4
不要将调用函数与parens一起使用!!!由于您可以使用bash在bash中定义一个函数,function fname { echo "Inside fname"; return 0; }或者fname() { echo "inside fname"; return 0; }将parens放在函数调用上,这看起来像是函数定义。功能应该被称为像任何其他的命令行程序,如mvcprsynclscd,等...在这种情况下,我们称之为FNAME像这样:fname $ARGS
查尔斯·亚迪斯

do_nothing()是跳过语句?使用:
sjas 2016年

Answers:


309

将竖线(|)用作“或”。

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

30
或在这种简单情况下,一个角色类[23])
SiegeX 2011年

4
@Mischka-我注意到您尚未接受此答案,是因为它没有回答问题的贯穿部分?在需要进行特殊处理之前do_what_you_are_supposed_to_do(),如果将“ 2”和“ 3”都折叠成一个单独的大小写不能解决此问题,则fallthrough逻辑很有用。我不确定是否可以编辑问题以使这一点更清楚,因为很明显很多人发现此答案很有帮助。
泰森

1
@Tyson OP未接受答案,因为它是未注册的用户。至于程序员通常理解的“直通”逻辑,问题主体表现出条件的崩溃,而不是直通逻辑。(请注意break在php代码中使用。)此时,编辑问题或其标题将使许多确实提供无效逻辑的答案无效,并且可能不应该这样做。直到其他用户进行几次编辑后,标题才出现掉线,但现在将其撤回为时已晚。
user7412956 '19

100

最新bash版本允许使用;&代替来掉线;;:它们还允许使用来恢复案例检查;;&

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

样本输出

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

1
在此示例中,此逻辑很难遵循。另外,我不认为这个例子实际上证明之间的差异;&;;&。我改变了"24";;& # resume并得到了相同的结果,所以我一直在想什么时候使用;&的下通。
wisbucky

1
这是一件复杂事情的简单示例-我更改?4[13]4使其更明显,并使您的更改成为重大更改
Jasen

26
  • ()除非要定义它们,否则请勿在bash中使用后面的函数名称。
  • 使用[23]以匹配23
  • 静态字符串大小写应使用''而不是""

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

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

对于不区分大小写的匹配,可以使用字符类(例如[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

但是abra没有打中,因为它将与第一种情况相匹配。

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


case "${C,,}" in如果大小写不重要,也可以将C转换为小写
Sprinterfreak 2014年

1
如果您忽略该;;怎么办?您不应该使用这种;&方法吗?
HelloGoodbye

1
如果我想继续测试,则忽略;; 需要使用的语法错误;;&
杰森

do_wild_mysterious_things我的一天
朱利安(Julien__)


13

如果值是整数,则可以使用[2-3],也可以[5,7,8]用于非连续值。

#!/bin/bash
while [ $# -gt 0 ];
do
    case $1 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

如果值是字符串,则可以使用|

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

最后shift的目的是什么?
Milkncookiez

1
shift删除CLI参数列表上的第一个参数。基本上,在此循环的每次迭代中,总是$1使用来从CLI参数列表中获取每个参数shift
rashok
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.