
Bash的运算符、正则表达式
一、Bash的运算符和基本运算
1.1、 declare声明变量类型
declare格式:
declare [+/-] [选项] [变量名]
-:给变量设定类型属性
+:取消变量的类型属性
选项:
-a :将变量声明为数组型
-i :将变量声明为整数型(integer)
-x :将变量声明为环境变量 等同于: export a=100
-r :将变量声明为只读变量
-p :显示指定变量的被声明类型
- 示例
# 变量声明为整数型
declare -i a=100
# 把变量定义成数组型
declare -a name[0]=zhangsan ##定义数组,name代表数组,[0]代表下标,默认0开始,“=”后代表数组的值
declare -a name[1]=lisi
declare -a name[2]=wangwu
# 把变量定义成环境变量
declare -x test=123
# 只读变量
declare -r test
# 查看变量属性
declare -p test
1.2、bash的运算符分类
1、算术运算符
2、关系运算符
3、布尔运算符
4、字符串运算符
5、文件测试运算符
1.2.1、算术运算符
格式1:$((算数运算符))
格式2:((表达式1,表达式2…))
格式3:[表达式]
特点:
1、在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。a++ 等价于 a=a+1
2、在双括号结构中,所有变量可以不加入:“$”符号前缀。
3、双括号可以进行逻辑运算,四则运算
4、双括号结构 扩展了for,while,if条件测试运算((a=1,a<10,a++))
5、支持多个表达式运算,各个表达式之间用“,”分开
常用的算数运算符
运算符 | 意义 |
---|---|
++ -- | 递增及递减,可前置也可以后置 |
+ - ! ~ | 一元运算的 正 、负、 取反 、逻辑与 |
+ - * / % | 加减乘除与余数 |
< <= > >= | 比较大小符号 |
== != | 相等 不相等 |
&& || | 逻辑与 逻辑或 |
? | 条件判断 |
Shell变量的算术运算:expr
- 示例
# 数值计算
var1=8
var2=2
expr $var1 \* $var2
# 计算字符串长度
[root@myx~]$ expr length "hello world"
11
# 抓取字符串中特定的字串
[root@myx~]$ expr substr "hello world" 7 5
world
赋值表达式:let
格式:
let 赋值表达式
【注】let赋值表达式功能等同于:((赋值表达式))
示例
i++ # 先赋值再自增
++i # 先自增再赋值
i-- # 先赋值再自减
--i # 先自减再赋值
示例:打印随机颜色
echo $RANDOM 范围0-32767
echo -e "\e[1;$[RANDOM%7+31]mhello\e[0m"
# 跑马灯名字颜色
PS1='[\[\e[$[RANDOM%7+31]m\]\u\[\[\e[$[RANDOM%7+31]m\]@\[\[\e[$[RANDOM%7+31]m\]\h\[\[\e[$[RANDOM%7+31]m\]\w]\[\[\e[$[RANDOM%7+31]m\]$ \[\[\e[$[RANDOM%7+31]m\]'
1.2.2、关系运算符
1) 关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 100,变量 b 为 200:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
示例:判断是否是管理员
[root@localhost ~]# [ $(id -u) -eq 0 ] &&echo "your are admin" || echo "your are not admin"
your are admin
1.2.3、布尔运算符
1)下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
布尔运算符实例:
[root@localhost ~]# [ $a -lt 20 -o $b -gt 100 ] && echo yes || echo no
yes
[root@localhost ~]# [ $a -lt 20 -a $b -gt 100 ] && echo yes || echo no
no
1.2.4、字符串运算符
1)下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -n $a ] 返回 true。 |
str | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
2)字符串运算符示例:
[root@localhost ~]# [ $a != $b ] && echo yes || echo no
yes
1.2.5、文件测试运算符
1)文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是具名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
-L file | 检测文件是否是链接文件,是否有效,如果是,则返回 true。 | [ -L $file ] 返回 true。 |
示例
# 判断文件是否存在
[root@localhost ~]# [ -e a ] ##用于判断a文件是否存在,存在则为真(0)
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ -e abc ] ##判断abc文件是否存在,不存在则为假(1)
[root@localhost ~]# echo $?
1
# 判断是否是链接文件 是否有效
[root@localhost ~]# touch file1.txt
[root@localhost ~]# ln -s file1.txt file1.txt.bak
[root@localhost ~]# [ -e file1.txt.bak -a -L file1.txt.bak ]&&echo yes || echo no
yes
2)两个文件之间进行比较
文件1 -nt 文件2 判断文件1修改的时间是否比文件2的新,如果新则为真
文件1 -ot 文件2 判断文件1修改的时间是否比文件2的旧,如果旧则为真
文件1 -ef 文件2 判断文件1和文件2的INODE号是否一致,如果一致则为真
3) 变量测试判断
-v VAR_NAME ##判断变量是否被定义
注:只判断该变量是否被定义,所以即使定义的是空值也为 真
示例:
[root@localhost ~]# [ -v b ] && echo yes || echo no ##b变量已经被定义,则为真
yes
[root@localhost ~]# [ -v c ] && echo yes || echo no ##c变量没有被定义,则为假
no
1.3、 [[ ]]的应用
1.3.1 示例1:对空值的判断区别
[ ] 无法使用通配符和正则表达式,但是[[ ]]是可以匹配通配符和正则表达式
[root@localhost ~]# [ "$name" = hello ]&& echo yes ||echo no
no
[root@localhost ~]# [[ $name = hello ]]&& echo yes ||echo no
no
注意:“==”表示通配符,“=~”表示正则表达式
1.3.2 [[ ]]示例:通配符和正则判断
##通配符
[root@localhost ~]# name=file.txt
[root@localhost ~]# [[ "$name" == *.txt ]] && echo yes || echo no
yes
[root@localhost ~]# [[ "$name" == *.log ]] && echo yes || echo no
no
[root@localhost ~]# [[ "$name" != *.log ]] && echo yes || echo no
yes
##正则表达式
##匹配.log结尾
[root@localhost ~]# name=file.txt
[root@localhost ~]# [[ "$name" =~ \.log$ ]] && echo yes || echo no
no
[root@localhost ~]# [[ "$name" =~ \.txt$ ]] && echo yes || echo no
yes
##匹配数字结尾
[root@localhost ~]# num=10
[root@localhost ~]# [[ "$num" =~ ^[0-9]+$ ]] &&echo yes || echo no
yes
##匹配字母结尾
[root@localhost ~]# num1=10a
[root@localhost ~]# [[ "$num1" =~ ^[a-z]$ ]] &&echo yes || echo no
no
[root@localhost ~]# [[ "$num1" =~ [a-z]+$ ]] &&echo yes || echo no
yes
##匹配数字结尾
[root@localhost ~]# num2=a10
[root@localhost ~]# [[ "num2" =~ [0-9]+$ ]] &&echo yes || echo no
yes
##匹配IP地址
[root@localhost ~]# ip=192.168.1.1
[root@localhost ~]# [[ "$ip" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]] && echo yes || echo no
yes
[root@localhost ~]# ip=1111.2222.2222.111a
[root@localhost ~]# [[ "$ip" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] && echo yes || echo no
no
[root@localhost ~]# ip=1111.2222.2222.1119
[root@localhost ~]# [[ "$ip" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] && echo yes || echo no
no
[root@localhost ~]# ip=1.22.2.111
[root@localhost ~]# [[ "$ip" =~ ^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] && echo yes || echo no
yes
##另一种写法
[root@localhost ~]# [[ "$ip" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] && echo yes || echo no
yes
1.3.2 关于[[ == ]]双等(==)号右边的双引号的说明:
示例:
[root@localhost ~]# name=wcfeng123
[root@localhost ~]# [[ "$name" == wcfeng* ]] && echo yes || echo no
yes
[root@localhost ~]# [[ "$name" == "wcfeng*" ]] && echo yes || echo no
no
[root@localhost ~]# [[ "$name" == wcfeng\* ]] && echo yes || echo no
no
1.4、 {}和()的区别
( )
:在小括号中定义的变量的值将不会影响父shell中定义的变量的值
{ }
: 在花括号中定义的变量的值将会影响父shell中定义的变量的值
# 小括号写法
(echo $name)
# 大括号写法
{ echo $name; }
##注意{}的写法,在{ 后需要加空格,在}之前也需要空格,并加;结束
拓展
- 判断服务器的根分区的使用率是否超过80%,如果超过了,则给自己的邮箱发一份邮件
#!/bin/bash
DISK_USED=`df -h | grep "/$" | tr -s ' ' | cut -d' ' -f5 | grep -o [0-9]*`
[ "$DISK_USED" -ge 30 ] && echo "你的磁盘占用已经达到"$DISK_USED%",请及时清理
!" | mail -s '磁盘告急' 2041598918@qq.com
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 梦缘羲
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果