切换机箱有穿透?

Mis*_*hka 176 bash switch-statement

我正在寻找switch语句的正确语法与Bash中的初级案例(理想情况下不区分大小写).在PHP中我会编程它像:

switch($c) {
    case 1:
        do_this();
        break;
     case 2:
     case 3:
        do_what_you_are_supposed_to_do();
        break;
     default:
        do_nothing(); 
}
Run Code Online (Sandbox Code Playgroud)

我希望在Bash中也一样:

case "$C" in
    "1")
        do_this()
        ;;
    "2")
    "3")
        do_what_you_are_supposed_to_do()
        ;;
    *)
        do_nothing();
        ;; 
esac
Run Code Online (Sandbox Code Playgroud)

这在某种程度上是行不通的:do_what_you_are_supposed_to_do()当$ C为2或3时,应该触发函数.

gee*_*aur 286

使用竖条(|)表示"或".

case "$C" in
"1")
    do_this()
    ;;
"2" | "3")
    do_what_you_are_supposed_to_do()
    ;;
*)
    do_nothing()
    ;;
esac
Run Code Online (Sandbox Code Playgroud)

  • 或者在这个简单的例子中是一个字符类`[23])` (25认同)
  • @Mischka - 我注意到你没有接受这个答案,那是因为它没有回答问题的初步部分吗?在`do_what_you_are_supposed_to_do()`之前应该进行特殊处理,将"2"和"3"折叠成单个案例无法解决这个问题.我不确定编辑问题是否合理,因为很明显很多人都认为这个答案很有帮助. (3认同)
  • @Tyson OP 尚未接受答案,因为它是未注册用户。至于“落空”逻辑,正如程序员通常理解的那样,问题主体展示了条件的崩溃,而不是落空逻辑。(请注意 php 代码中使用“break”。)此时编辑问题或其标题将使许多_do_提供失败逻辑的答案无效,并且可能不应该这样做。直到其他用户进行了多次编辑后,标题中才出现了“失败”的字样,但现在将其撤回已为时已晚。 (2认同)

Jas*_*sen 88

最新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" | ?4)
     echo -n four 
     ;;&  # resume ( to find teen where needed )
   "14" )
     echo -n teen
  esac
  echo 
done
Run Code Online (Sandbox Code Playgroud)

样本输出

4 = four
14 = fourteen
24 = twenty-four
34 = thirty-four
Run Code Online (Sandbox Code Playgroud)

  • 这个例子中的逻辑很难遵循。另外,我不认为这个例子真正展示了 `;&` 和 `;;&` 之间的区别。我将“24”更改为“;;&#resume”并得到了相同的结果,所以我仍然想知道什么时候会使用“;&”fallthrough。 (2认同)
  • 这是一个复杂事物的简单示例 - 我将 `?4` 更改为 `[13]4` 以使其更加明显,并使您的更改成为重大更改 (2认同)

Spr*_*eak 25

  • ()除非您想定义它们,否则不要在bash中使用函数名称.
  • 用于[23]匹配23
  • 静态字符串的情况应该用括号''代替""

如果括起来"",解释器(不必要地)尝试在匹配之前扩展值中的可能变量.

case "$C" in
'1')
    do_this
    ;;
[23])
    do_what_you_are_supposed_to_do
    ;;
*)
    do_nothing
    ;;
esac
Run Code Online (Sandbox Code Playgroud)

对于不区分大小写的匹配,您可以使用字符类(如[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
Run Code Online (Sandbox Code Playgroud)

但是abra没有随时打,因为它将与第一个案例相匹配.

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


Ren*_*amp 13

试试这个:

case $VAR in
normal)
    echo "This doesn't do fallthrough"
    ;;
special)
    echo -n "This does "
    ;&
fallthrough)
    echo "fall-through"
    ;;
esac
Run Code Online (Sandbox Code Playgroud)

  • 注意:这对于bash 3.2无效,后者仍是macOS中的默认bash。 (3认同)

ras*_*hok 12

如果值是整数,那么您可以使用[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
Run Code Online (Sandbox Code Playgroud)

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

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

  • `shift` 删除 CLI 参数列表中的第一个参数。基本上,在这个循环的每次迭代中,总是使用“$1”在“shift”的帮助下从 CLI 参数列表中获取每个参数。 (2认同)