case word in [pattern [| pattern]...) commands ;;]... esac
举个例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#!/bin/bash # case4-1: test a character read -n 1 -p "Type a character > " echo case$REPLYin [[:upper:]]) echo"'$REPLY' is upper case." ;; [[:lower:]]) echo"'$REPLY' is lower case." ;; [[:alpha:]]) echo"'$REPLY' is alphabetic." ;; [[:digit:]]) echo"'$REPLY' is a digit." ;; [[:graph:]]) echo"'$REPLY' is a visible character." ;; [[:punct:]]) echo"'$REPLY' is a punctuation symbol." ;; [[:space:]]) echo"'$REPLY' is a whitespace character." ;; [[:xdigit:]]) echo"'$REPLY' is a hexadecimal digit." ;; esac
case 命令检查一个变量值,在上述例子中,就是 REPLY 变量的变量值,然后试图去匹配其中一个具体的模式(模式以一个 “)” 为终止符),当与之相匹配的模式找到之后,就会执行与该模式相关联的命令,并且在该例子中找到一个模式之后,就不会再继续寻找
1 2 3
$ ./case4-1 Type a character > a 'a' is lower case. # 但其实 a 既是小写字母,也是一个十六进制的数字,但是上述例子在找到一个模式之后,无法再继续寻找新的模式
以前一直觉得 case 命令是只能执行某一个模式之后对应的命令(事实上早于版本号 4.0 的 bash,case 语法的确只允许执行与一个成功匹配的模式相关联的动作),而现如今则不然,现在的 bash 版本,可以添加 “;;&” 表达式来终止每个行动,并且允许 case 语句继续匹配下一条模式,而不是简单地终止运行
于是上述例子可以改成以下写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#!/bin/bash # case4-2: test a character read -n 1 -p "Type a character > " echo case$REPLYin [[:upper:]]) echo"'$REPLY' is upper case." ;;& [[:lower:]]) echo"'$REPLY' is lower case." ;;& [[:alpha:]]) echo"'$REPLY' is alphabetic." ;;& [[:digit:]]) echo"'$REPLY' is a digit." ;;& [[:graph:]]) echo"'$REPLY' is a visible character." ;;& [[:punct:]]) echo"'$REPLY' is a punctuation symbol." ;;& [[:space:]]) echo"'$REPLY' is a whitespace character." ;;& [[:xdigit:]]) echo"'$REPLY' is a hexadecimal digit." ;;& esac
这时候再执行
1 2 3 4 5 6
$ ./case4-2 Type a character > a 'a' is lower case. 'a' is alphabetic. 'a' is a visible character. 'a' is a hexadecimal digit.