简介
? case
语句是一种多路分支结构,用于根据变量的值来判断执行不同的命令。作用与 if 有着异曲同工之妙,在某些地方比 if 可能更加好用,这里就介绍一些 case 的用法与实践,if 的详细方法见另一篇文章:shell if判断的应用方法-CSDN博客
????????
文章目录如下
????????
case [var] in # var是需要判断的变量名,case in是固定的
str1) # 判读var变量是str1
command1 # 如果变量是"str1",则执行这里的命令
;; # 固定结尾语法
str2) # 判读var变量是str2
command2 # 如果变量是"str2",则执行这里的命令
;; # 固定结尾语法
*) # 如果变量既不是str1又不是str2,那么执行这里的命令
command3 # 自定义命令
;; # 固定结尾语法
esac # 固定case的结尾语法
case 语法的开头是 case 变量 in ,意思就是使用 case 语法读取某个变量,根据变量不同的结果执行不同的命令。
esac 是语法的结尾符,就是 case 倒过来写。
????????
【例子】如果参数为1,调用函数Func1的方法;如果参数为2,调用函数Func2的方法;如果不是1或2,则调用函数Func3的方法。
# 封装3个函数
Func1(){
echo "我是函数1"
}
Func2(){
echo "我是函数2"
}
Func3(){
echo "我是函数3"
}
# 使用case判断参数
case $1 in # 判断位置参数1的结果
1) # 如果为1,执行下面的代码
Func1
;;
2) # 如果为2,执行下面的代码
Func2
;;
*) # 如果非1或2,执行下面的代码
Func3
;;
esac # 结束语法
结果如下
- 参数为1,执行函数1。
- 参数为2,执行函数2。
- 参数非1或2,执行函数3。
????????
不论是位置参数还是变量,我们都可以使用这种方法判断
# 定义一个变量
var="A"
# 判断这个变量
case ${var} in
A)
echo "变量为A"
;;
*)
echo "变量不为A"
;;
esac
????????
也可以直接使用命令来做判断
# 判断命令的结果
case $(ls file.txt) in
file.txt)
echo "有file.txt这个文件"
;;
*)
echo "没有file.txt这个文件"
;;
esac
????????
case 除了可以直接使用,也支持语句嵌套
# 定义2个变量
a=$1
b=$2
# 判断变量a
case ${a} in
1)
# 如果a为1,判断b
case ${b} in
2)
echo "a=1, b=2"
;;
*)
echo "a=1, b!=2"
;;
esac
;;
*)
echo "a!=1"
;;
esac
????????
正则表达式能够将 case 的用法完全发挥,这里列举3种常用的方法。
yes|YES|Yes) # 使用 | 分割
基本语法在《目录1》已经介绍过,平时使用最多就是判断某个变量是否=xxx。这些变量可以自定义,也可以通过某些命令获取的值。当出现多个值时,那么使用固定的值判断就显得有些局限。需求如下:
# 定义一个变量
var="$1"
# 封装3个函数
Func1(){
echo "我是yes指定的函数1"
}
Func2(){
echo "我是no指定的函数2"
}
Func3(){
echo "我是非yes或no指定的函数3"
}
# 使用case判断参数
case ${var} in
yes|YES|Yes)
Func1
;;
no|NO|No)
Func2
;;
*)
Func3
;;
esac
结果如下
????????
字符*) 或者 *字符) # *匹配0个或多个字符
字符?) 或者 ?字符) # ?匹配1个字符
当获取的变量存在多个字符,但只能确定字符中包括xxx字符时,那么通配符的作用就展示出来了。需求如下:
path=$(pwd)
case ${path} in
*/file*)
echo "当前路径包含 file 目录"
;;
*)
echo "当前路径不包含 file 目录"
;;
esac
*/file* 表示?/file 左右可以出现任意字符。
*/file? 表示?/file 左边可以出现任意字符。
/file*? 表示?/file 右边可以出现任意字符。
????????
除了常用的 * 符号,还有一个不常用的 ? 符号,来看一个例子
case $1 in
"a"?)
echo "位置参数为a+1个任意字符"
;;
?"a")
echo "位置参数为任意1个字符+a"
;;
*)
echo "位置参数为a或者其他"
;;
esac
使用 ? 符号挨着需要匹配的字符串旁边。以匹配字符 a 为例,表示匹配变量为2个字符。
????????
【案例一】匹配一个大写字母 [A-Z]
case "$1" in
[A-Z])
echo "这是1个大写字母"
;;
esac
????????
【案例二】匹配一个小写字母?[a-z]
case "$1" in
[a-z])
echo "这是1个小写字母"
;;
esac
????????
【案例三】匹配一个数字?[0-9]
case "$1" in
[0-9])
echo "这是1个数字"
;;
esac
????????
【案例四】匹配一个数字或字母(不包括特殊字符)[0-9] |?[a-z] |?[A-Z]
case "$1" in
[0-9]|[a-z]|[A-Z])
echo "这是1个数字或字母"
;;
esac
也可以这样写?[0-9a-zA-Z]
case "$1" in
[0-9a-zA-Z])
echo "这是1个数字或字母"
;;
esac
?????????
【案例五】匹配多个字母或多个数字?[0-9][0-9][0-9]
case "$1" in
[0-9][0-9][0-9])
echo "这是3个数字"
;;
[a-z][a-z][a-z])
echo "这是3个小写字母"
;;
[A-Z][A-Z][A-Z])
echo "这是3个大写字母"
;;
esac
case 中匹配多个字符只有使用多个 [ ][ ][ ]?的方法,[a-z]{次数} 这种方式在case中不支持。
????????
【案例六】匹配以a开头的字符 a*
case "$1" in
a*)
echo "这是1个以a开头的字符"
;;
esac
????????
【案例七】匹配以a结尾的字符?*a
case "$1" in
*a)
echo "这是1个以a结尾的字符"
;;
esac
????????
需求如下:
# 读取某个值赋值给变量
var=$(ip route get 8.8.8.8 |awk -F ' src' 'NR==1{print $1}' |awk '{print $NF}')
case ${var} in
"ens33")
echo "执行A方法"
;;
"ens192")
echo "执行B方法"
;;
*)
var="ens100"
echo "var的值超过范围,重新定义后执行C方法"
;;
esac
????????
方法参考《2.3. 正则表达式匹配》,需求如下:
case "$1" in
192.[0-9][0-9][0-9].[0-9][0-9][0-9].[0-9][0-9][0-9])
echo "这是1个以192开头,全3位的IP"
;;
*)
echo "IP不正确"
;;
esac
????????
需求如下:
while read -p "是否删除文件file1.txt: " r;do
case ${r} in
yes|YES|y|Y)
echo "删除文件file1.txt后退出"
rm -rf file1.txt
break
;;
no|NO|n|N)
echo "不删除文件file1.txt,直接退出"
break
;;
esac
done
结果如下
????????
需求如下:
case "$1" in
*.txt)
echo "这是一个文本文件,执行xxx"
;;
*.jpg | *.png)
echo "这是一个图片文件,执行xxx"
;;
*)
echo "该文件不符合需求,执行xxx"
;;
esac
????????