Shell也支持两种分支结构(选择结构),分别是 if else 语句和 case in 语句。当分支较多,并且判断条件比较简单时,使用 case in 语句就比较方便了。
if else 语句与case in语句的对比
| 脚本 | 易错点与知识点 |
if else语句 |
- #!/bin/bash
- read -p 'please input the month: ' month
- if ((month>=3 && month<=5))
- then echo 'spring'
- elif ((month>=6 && month<=8))
- then echo 'summer'
- elif ((month>=9 && month<=11))
- then echo 'autumn'
- elif ((month==12 ||(month<=2&&month>0)))
- then echo 'winter'
- else
- echo 'the month is error'
- fi
|
- 使用((month==12 ||(month<=2&&month>0)))时,注意使用()将复杂逻辑括起来,避免混淆
- 使用((month==12 ||(month<=2&&month>0)))时,只能用month==12不能month=12,因为使用month=12会将month重新赋值,影响后续判断
|
case in语句 |
- !/bin/bash
- read -p 'please input the month: ' month
- case $month in
- [3-5])
- echo 'spring';;
- [6-8])
- echo 'summer';;
- 9|10|11)
- echo 'autumn';;
- 12|1|2)
- echo 'winter';;
- *)
- echo 'the month is error'
- esac
|
- 不能使用[9-11]代表9到11的范围
- 使用|表示多重选择
|
case in语句的用法
用法 | 说明 |
case expression in pattern1) statement1 ;; pattern2) statement2 ;; pattern3) statement3 ;; …… *) statementn esac |
1. case、in 和 esac 都是 Shell 关键字,expression 表示表达式,pattern 表示匹配模式。
-
- expression 既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到 expression 的值就可以。
- pattern 可以是一个数字、一个字符串,甚至是一个简单的正则表达式。
2. case 会将 expression 的值与 pattern1、pattern2、pattern3 逐个进行匹配:
-
- 如果 expression 和某个模式(比如 pattern2)匹配成功,就会执行这模式(比如 pattern2)后面对应的所有语句(该语句可以有一条,也可以有多条),直到遇见双分号
;; 才停止;然后整个 case 语句就执行完了,程序会跳出整个 case 语句,执行 esac 后面的其它语句。
- 如果 expression 没有匹配到任何一个模式,那么就执行
*) 后面的语句(* 表示其它所有值),直到遇见双分号;; 或者esac 才结束。*) 相当于多个 if 分支语句中最后的 else 部分。
3. 对*) 的几点说明:
-
- *)部分可以省略,
*) 部分主要用于在 expression 没有匹配到任何一个模式时做一些“善后”工作,或者给用户一些提示
除最后一个分支外(这个分支可以是普通分支,也可以是*) 分支),其它的每个分支都必须以;; 结尾,;; 代表一个分支的结束,不写的话会有语法错误。最后一个分支可以写;; ,也可以不写,因为无论如何,执行到 esac 都会结束整个 case in 语句。
|
case in 和正则表达式
case in 的 pattern 部分支持简单的正则表达式,具体来说,可以使用以下几种格式:
格式 | 说明 |
* |
表示任意字符串。 |
[abc] |
表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。 |
[m-n] |
表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。 |
| |
表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 "abc" 或者 "xyz"。 |
如果不加以说明,Shell 的值都是字符串,expression 和 pattern 也是按照字符串的方式来匹配的;最后一个分支*)
并不是什么语法规定,它只是一个正则表达式,*
表示任意字符串,所以不管 expression 的值是什么,*)
总能匹配成功。
下面的例子演示了如何在 case in 中使用正则表达式:
脚本 | 结果 |
- printf "Input a character: "
- read -n 1 char
- case $char in
- [a-zA-Z])
- printf "
letter
"
- ;;
- [0-9])
- printf "
Digit
"
- ;;
- [,.?!])
- printf "
Punctuation
"
- ;;
- *)
- printf "
error
"
- esac
|
运行结果1: Input integer number: S letter
运行结果2: Input integer number: , Punctuation |