Day...2
1.子串:
1.子串切片
[root@shell ~]# name="I am majunnan" [root@shell ~]# echo ${name:2:2} # 从第二个字符串后开始,截两个字符串 am [root@shell ~]# echo ${name:2:4} # 从第二个字符串后开始,截四个字符串 am m
2.统计子串长度
1.第一种统计方式:
[root@shell ~]# echo $name|wc -L 13
2.第二种统计方式:
[root@shell ~]# echo $name|awk '{print length}' 13
3.第三种统计方式:
[root@shell ~]# expr length "$name" 13
4.第四种统计方式:
[root@shell ~]# echo ${#name} 13
5.统计长度小于3的字符串
[root@shell ~]# echo I am majunnan I am 18|xargs -n1 I am majunnan I am 18 [root@shell ~]# echo I am majunnan I am 18|xargs -n1|awk '{print length}' 1 # 把 I 拿到awk中,做动作打印print,打印字符串长度length 2 # 把 am 拿到awk中,做动作打印print,打印字符串长度length 8 # 以此上类推 1 2 2 [root@shell ~]# echo I am majunnan I am 18|xargs -n1|awk '{if(length<3)print}' I # 把 I 拿到awk中,字符串长度length小于3的,打印字符串 am # 把 am 拿到awk中,字符串长度length小于3的,打印字符串 I # 以此上类推 am 18
6.AWK以列为单位统计长度小于3的字符串
[root@shell ~]# echo I am majunnan I am 18|awk '{for(i=1;i<=NF;i++)if(length($i)<3)print $i}' I # i从字符串第一 I 列开始,到字符串最后一列 18 结束,依次向后递增 am # 判断,当 i 表示的字符串长度小于3时,打印此时的字符串 I am 18
7.shell使用for循环方式
[root@shell ~]# cat for.sh #!/bin/bash for i in I am majunnan I am 18 do echo ${#i} done [root@shell ~]# sh for.sh 1 2 8 1 2 2 [root@shell ~]# cat for.sh #!/bin/bash for i in I am majunnan I am 18 do [ ${#i} -lt 3 ] && echo $i done [root@shell ~]# sh for.sh I am I am 18
3.子串删除,支持通配符
1.#从前往后删除,##贪婪匹配
[root@shell ~]# url=www.baidu.com [root@shell ~]# echo $url www.baidu.com [root@shell ~]# echo ${url#www.} baidu.com [root@shell ~]# echo ${url#*.} baidu.com [root@shell ~]# echo ${url#*.*c} om [root@shell ~]# echo ${url#*.*.} com [root@shell ~]# echo ${url##*.} com
2.%从后往前删除,%%贪婪匹配
[root@shell ~]# echo $url www.baidu.com [root@shell ~]# echo ${url%.*} www.baidu [root@shell ~]# echo ${url%.*.*} www [root@shell ~]# echo ${url%%.*} www
3.子串的替换,/替换谁/替换成谁,//替换谁/替换成谁,贪婪替换
[root@shell ~]# echo $url www.baidu.com [root@shell ~]# echo ${url/w/W} Www.baidu.com [root@shell ~]# echo ${url/www/WWW} WWW.baidu.com [root@shell ~]# echo ${url//w/W} WWW.baidu.com [root@shell ~]# echo ${url/baidu/sina} www.sina.com
4.子串小结
子串切片
${变量:2:2}
统计字符串长度
${#变量}
统计小于3的字符串
子串的删除 ## %%
子串的替换 // ///
2.数值运算:
# 随机数取余数 RANDOM 0-32767之间的数字 [root@shell scripts]# echo $((RANDOM%100+1)) # 1-100取随机数 82
1.expr 只支持整数运算,两边必须有空格
[root@shell ~]# expr majunnan # 类似echo,把后面内容输出到屏幕上 majunnan [root@shell ~]# expr 1 + 100 101 [root@shell ~]# expr 10 - 10 0 [root@shell ~]# expr 10 * 10 # 报错,需要转义 expr: syntax error [root@shell ~]# expr 10 \* 10 100 [root@shell ~]# expr 10 / 10 1 [root@shell ~]# expr 1 + 1.5 # 不支持非整数运算 expr: non-integer argument
案例: 判断传入的参数是否为整数、exit指定返回值
[root@shell /server/scripts]# cat expr.sh #!/bin/bash read -p "请输入你的年龄: " age expr 1 + $age &>/dev/null [ $? -ne 0 ] && echo "请输入整数" && exit echo $age [root@shell /server/scripts]# sh expr.sh 请输入你的年龄: 1.2 请输入整数 [root@shell /server/scripts]# sh expr.sh 请输入你的年龄: 12 12 [root@shell /server/scripts]# cat expr.sh #!/bin/bash read -p "请输入你的年龄: " age expr 1 + $age &>/dev/null [ $? -ne 0 ] && echo "请输入整数" && exit 100 echo $age [root@shell /server/scripts]# sh expr.sh 请输入你的年龄: 20.5 请输入整数 [root@shell /server/scripts]# echo $? 100
2.$(())只支持整数运算,注意不要和$()冲突,$()执行的命令和``相同
[root@shell /server/scripts]# echo $((10+10)) 20 [root@shell /server/scripts]# echo $((10-10)) 0 [root@shell /server/scripts]# echo $((10*10)) 100 [root@shell /server/scripts]# echo $((10/10)) 1
3.$[] 只支持整数运算
[root@shell /server/scripts]# echo $[10+10] 20 [root@shell /server/scripts]# echo $[10-10] 0 [root@shell /server/scripts]# echo $[10/10] 1 [root@shell /server/scripts]# echo $[10*10] 100 [root@shell /server/scripts]# echo $[10**10] # 幂运算,10的10次幂 10000000000
4.let 只支持整数运算,通过变量的方式
[root@shell ~]# let a=1+1 [root@shell ~]# echo $a 2 [root@shell ~]# let a=1*10 [root@shell ~]# echo $a 10
let i++ 等于 let i=i+1
[root@shell ~]# let i=i+1 [root@shell ~]# echo $i 1 [root@shell ~]# let i++ [root@shell ~]# echo $i 2 [root@shell ~]# let i=i+1 [root@shell ~]# echo $i 3
直接运算 ++i i++ 相同,都是自增1,unset + 变量,取消变量
[root@shell ~]# let ++a [root@shell ~]# echo $a 1 [root@shell ~]# unset a # unset + 变量,取消变量 [root@shell ~]# echo $a # 空,变量被取消 [root@shell ~]# let a++ [root@shell ~]# echo $a 1
在使用变量的情况下两个是有区别
i++ 先赋值再运算(字母在前,先赋值,再运算)i++ : i=1+1 先赋值再运算 i=1 之后 再 +1
++i 先运算再赋值(符号在前,先运算,再赋值)++i : 1+1=i 先运算再赋值 1+1 之后 再 =i
[root@shell ~]# unset a [root@shell ~]# a=1 [root@shell ~]# b=1 [root@shell ~]# let i=a++ # a=1,i=a=1 [root@shell ~]# let c=++b # c=b+1,b=1,c=2 [root@shell ~]# echo $i 1 [root@shell ~]# echo $c 2
5.bc 支持整数和小数运算
[root@shell ~]# echo 10+10|bc 20 [root@shell ~]# echo 10+10.5|bc 20.5 [root@shell ~]# echo 10*10.5|bc 105.0 [root@shell ~]# echo 10-10.5|bc -.5 [root@shell ~]# echo 10/10.5|bc 0
6.AWK 支持整数和小数运算
[root@shell ~]# awk 'BEGIN{print 10+10}' 20 [root@shell ~]# awk 'BEGIN{print 10-10}' 0 [root@shell ~]# awk 'BEGIN{print 10*10}' 100 [root@shell ~]# awk 'BEGIN{print 10/10}' 1 [root@shell ~]# echo 10 20|awk '{print $1+$2}' 30 [root@shell ~]# echo 10 20|awk '{print $1*$2}' 200 [root@shell ~]# echo 10 20|awk '{print $1/$2}' 0.5 [root@shell ~]# echo 10 20|awk '{print $1^$2}' # 10的20次幂 100000000000000000000
7.PYTHON 支持整数和小数运算
[root@shell ~]# python Python 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2 Type "help", "copyright", "credits" or "license" for more information. 10+10 # 输入 20 # 结果 10-10 0 10*10 100 10/10 1 # Crtl + d 退出
8.数值运算小结与案例
1)expr 1 + 100 整数运算
2)echo $((1 + 100)) 整数运算
3)echo $[1 + 100] 整数运算
4)let a=1+1 整数运算
5)let a++ 先赋值再运算与 let ++a 先运算再赋值 整数运算
6)bc 支持整数和小数运算
7)awk 'BEGIN{print 10+10}'
8)expr、$(())运算速度最快、$[]、let、bc、awk、python
案例: 使用read传参,写计算器案例,数字做判断,只能是整数,sh -x 显示脚本执行过程 结果输出: 10+20= 10-20= 10*20= 10/20= [root@shell /server/scripts]# cat count.sh #!/bin/sh read -p "请输入两个数字: " num1 num2 expr $num1 + $num2 &>/dev/null [ $? -ne 0 ] && echo "请输入整数" && exit 50 echo $num1+$num2=$[$num1+$num2] echo $num1-$num2=$[$num1-$num2] echo $num1*$num2=$[$num1*$num2] echo $num1/$num2=$[$num1/$num2] [root@shell /server/scripts]# sh -x 7.sh + read -p '请输入两个数字: ' num1 num2 请输入两个数字: 10 20 + expr 10 + 20 + '[' 0 -ne 0 ']' + echo 10+20=30 10+20=30 + echo 10-20=-10 10-20=-10 + echo '10*20=200' 10*20=200 + echo 10/20=0 10/20=0
3.条件表达式:
1.文件表达式语法结构
第一种: test -f 文件
[root@shell ~]# test -f /etc/host && echo "文件存在" || echo "文件不存在" 文件不存在 [root@shell ~]# test -f /etc/hosts && echo "文件存在" || echo "文件不存在" 文件存在
第二种: [ ] 常用,! 取反
[ -f /etc/hosts ] # 判断是否为普通文件 [ -d file ] # 目录存在则为真 [ -e file ] # 文件存在则为真 [ -r file ] # 文件可读则为真 [ -w file ] # 文件可写则为真 [ -x file ] # 文件可执行则为真
[root@shell ~]# [ -f /etc/passwd ] && echo "文件存在" || echo "文件不存在" 文件存在 [root@shell ~]# [ ! -f /etc/passwd ] && echo "文件存在" || echo "文件不存在" 文件不存在 [root@shell ~]# [ -f /etc/passwdddd ] && echo "文件存在" || echo "文件不存在" 文件不存在 [root@shell ~]# [ -d /etc/passwd ] && echo "目录存在" || echo "目录不存在" 目录不存在 [root@shell ~]# [ -d /etc/ ] && echo "目录存在" || echo "目录不存在" 目录存在 [root@shell ~]# [ -x /etc/ ] && echo "文件可执行" || echo "文件不可执行" 文件可执行 [root@shell ~]# ll -d /etc drwxr-xr-x. 79 root root 8192 Oct 19 09:14 /etc [root@shell ~]# [ -e /etc/ ] && echo "目录存在" || echo "目录不存在" 目录存在 [root@shell ~]# [ -w /etc/hosts ] && echo "文件可写" || echo "文件不可写" 文件可写
[root@shell ~]# dir=/tmp [root@shell ~]# [ -d $dir ] && echo "目录存在" || echo "目录不存在" 目录存在 [root@shell ~]# dir=/tmppppp [root@shell ~]# [ -d $dir ] && echo "目录存在" || echo "目录不存在" 目录不存在 [root@shell ~]# ls -d /etc/sysconfig/ /etc/sysconfig/ [root@shell ~]# [ -d `ls -d /etc/sysconfig/` ] && echo "目录存在" || echo "目录不存在" 目录存在
案例:
1. -d 判断目录是否存在,不存在则创建目录
[root@shell ~]# name=test [root@shell ~]# ip=`awk -F"=" '/IPADDR/{print $2 }' /etc/sysconfig/network-scripts/ifcfg-eth0` [root@shell ~]# echo $ip 10.0.0.201 [root@shell ~]# [ -d ${name}_$ip ] || mkdir ${name}_$ip
2. -f 判断函数库是否存在,存在则加载,functions,shell脚本的函数库
判断函数库是否存在,存在则加载 source与. 全局父shell生效
[root@shell ~]# action "hehe" /bin/true -bash: action: command not found [root@shell ~]# [ -f /etc/init.d/functions ] && . /etc/init.d/functions [root@shell ~]# action "hehe" /bin/true hehe
3.脚本中使用
[root@shell /server/scripts]# cat ping.sh #!/bin/sh [ -f /etc/init.d/functions ] && . /etc/init.d/functions ping -c1 -W1 $1 &>/dev/null [ $? -eq 0 ] && action "ping $1 is.." /bin/true || action "ping $1 is.." /bin/false [root@shell /server/scripts]# sh ping.sh www.baidu.com ping www.baidu.com is.. [ OK ] [root@shell /server/scripts]# sh ping.sh www.baidu.commmmmm ping www.baidu.commmmmm is.. [FAILED]
2.数值比较语法结构
第一种: test 整数1 比较符 整数2
第二种: [ 整数1 比较符 整数2 ]
比较符greater,equal,less,not equal
INTEGER1 -eq INTEGER2 等于 -eq INTEGER1 -ge INTEGER2 大于等于 -ge INTEGER1 -gt INTEGER2 大于 -gt INTEGER1 -le INTEGER2 小于等于 -le INTEGER1 -lt INTEGER2 小于 -lt INTEGER1 -ne INTEGER2 不等于 -ne
[root@shell ~]# test 10 -eq 10 && echo 成立 || echo 不成立 成立 [root@shell ~]# test 10 -ne 10 && echo 成立 || echo 不成立 不成立 [root@shell ~]# test 10 -ne 5 && echo 成立 || echo 不成立 成立 [root@shell ~]# [ 10 -eq 10 ] && echo 成立 || echo 不成立 成立 [root@shell ~]# [ 10 -ne 10 ] && echo 成立 || echo 不成立 不成立 [root@shell ~]# [ 15 -ne 10 ] && echo 成立 || echo 不成立 成立 [root@shell ~]# [ 15 -gt 10 ] && echo 成立 || echo 不成立 成立 [root@shell ~]# [ 10 -ge 10 ] && echo 成立 || echo 不成立 成立 [root@shell ~]# [ 10 -le 10 ] && echo 成立 || echo 不成立 成立
支持命令形式:tee命令用于读取标准输入的数据,并将其内容输出成文件
[root@shell ~]# [ 50 -gt `echo $((RANDOM%100))|tee file.txt` ] && echo "成立" || echo 不成立 成立 [root@shell ~]# cat file.txt 20 [root@shell ~]# [ 20 -eq `cat /etc/passwd|wc -l` ] [root@shell ~]# echo $? 0
[root@shell ~]# [ 10 -eq 10 -o 10 -gt 20 -o 20 -lt 10 ] && echo "成立" ||echo "不成立" 成立 [root@shell ~]# [ 10 -eq 10 -a 10 -gt 20 -o 20 -lt 10 ] && echo "成立" ||echo "不成立" 不成立 # -a把挨着自己的两个比较,整合成了一个,10 -eq 10 -a 10 -gt 20 或者 20 -lt 10 [root@shell ~]# [ 10 -eq 10 -a 10 -gt 20 -o 2 -lt 10 ] && echo "成立" ||echo "不成立" 成立 # -a把挨着自己的两个比较,整合成了一个,10 -eq 10 -a 10 -gt 20 或者 2 -lt 10
支持正则 [[]] && 并且 || 或者(注:单 [ ] 时与 -a -o一起使用,双[[ ]]时与&& ||一起使用)
[root@shell ~]# [[ 10 -eq 10 && 10 -gt 5 ]] && echo "成立" ||echo "不成立" 成立 [root@shell ~]# [[ 10 -eq 20 && 10 -gt 5 ]] && echo "成立" ||echo "不成立" 不成立 [root@shell ~]# [[ 10 -eq 20 || 10 -gt 5 ]] && echo "成立" ||echo "不成立" 成立
案例1
统计磁盘使用率,如果大于80%则发送邮件,否则输出当前使用率正常
查看磁盘使用率,df -h 取行(grep、sed、awk)
[root@shell ~]# df -h|awk 'NR==6' /dev/sda3 18G 1.9G 16G 11% / [root@shell ~]# df -h|grep /dev/sda3 /dev/sda3 18G 1.9G 16G 11% / [root@shell ~]# df -h|grep /$ # 以/结尾($以..结尾) /dev/sda3 18G 1.9G 16G 11% / [root@shell ~]# df -h|sed -n '/\/$/p' # 以/结尾,\转译 /dev/sda3 18G 1.9G 16G 11% / [root@shell ~]# df -h|awk '/\/$/' /dev/sda3 18G 1.9G 16G 11% / [root@shell ~]# df -h|awk '/\/$/'|awk '{print $(NF-1)}' # 取百分比 11%
脚本中与值进行比较
[root@shell /server/scripts]# cat disk.sh #!/bin/sh use_disk=`df -h|awk '/\/$/'|awk '{print $(NF-1)}'` [ ${use_disk%\%} -gt 10 ] && echo "send mail......" || echo "磁盘使用率正常 当前使用率为: $use_disk" # 第一个%子串代表从后往前删除,\%转译和删除%
案例2
内存使用百分比,大于5报警,小于5输出正常值
统计百分比
[root@shell ~]# free|awk 'NR==2{print $3/$2*100}' 8.49266 [root@shell /server/scripts]# cat free.sh #!/bin/sh use_free=`free|awk 'NR==2{print $3/$2*100}'` [ $use_free -gt 5 ] && echo "send mail......" || echo "内存使用率正常 当前使用率为: $use_free"
案例3
[root@shell /server/scripts]# cat diff.sh #!/bin/sh [ $1 -gt $2 ] && echo "$1>$2" [ $1 -lt $2 ] && echo "$1<$2" [ $1 -eq $2 ] && echo "$1=$2" [root@shell scripts]# sh diff.sh 20 30 20<30 [root@shell scripts]# sh diff.sh 20 10 20>10 [root@shell scripts]# sh diff.sh 20 20 20=20
案例4
无限循环,可使用exit或sleep退出和停止,true为真,任意事实都可以无限循环,例如:10=10
[root@shell /server/scripts]# cat diff.sh #!/bin/sh while true do read -p "请输入两个整数: " num1 num2 expr $num1 + $num2 &>/dev/null [ $? -ne 0 ] && echo "请输入整数" && exit 2 [ $num1 -gt $num2 ] && echo "$num1>$num2" [ $num1 -lt $num2 ] && echo "$num1<$num2" [ $num1 -eq $num2 ] && echo "$num1=$num2" done
案例5
[root@shell ~]# echo $RANDOM|md5sum |cut -c1-8 2d8a8c96 [root@shell ~]# echo $RANDOM|md5sum |cut -c1-8 caae07ff
4.字符串比对:
语法结构
[root@shell ~]# [ "root" = "root" ] && echo 成立 || echo 不成立 成立 [root@shell ~]# [ "roo" = "root" ] && echo 成立 || echo 不成立 不成立 [root@shell ~]# [ ! "roo" = "root" ] && echo 成立 || echo 不成立 成立 [root@shell ~]# [ $USER = "root" ] && echo 成立 || echo 不成立 # $USER为系统定义的变量 成立 [root@shell ~]# [ root = root -a user = user ] && echo 成立 || echo 不成立 成立 [root@shell ~]# [ oot = root -a user = user ] && echo 成立 || echo 不成立 不成立 [root@shell ~]# [ oot = root -o user = user ] && echo 成立 || echo 不成立 成立
[root@shell ~]# AAA="" [root@shell ~]# [ -z $AAA ] && echo 成立 || echo 不成立 成立 [root@shell ~]# AAA="aaa" [root@shell ~]# [ -z $AAA ] && echo 成立 || echo 不成立 不成立 [root@shell ~]# [ -n $AAA ] && echo 成立 || echo 不成立 成立
正则比对,^以...开头,$以...结尾
[root@shell ~]# [[ root =~ ^r ]] && echo 成立 || echo 不成立 # [[ ]]为正则,以^r会默认匹配^r,以=~ ^r为正则匹配 成立 [root@shell ~]# [[ root =~ t$ ]] && echo 成立 || echo 不成立 成立 [root@shell ~]# [[ $USER =~ t$ ]] && echo 成立 || echo 不成立 成立
[root@shell ~]# AAA="BBB" [root@shell ~]# [[ $AAA =~ ^[A-Z]+ ]] && echo 成立 || echo 不成立 成立 [root@shell ~]# AAA="BB1B" [root@shell ~]# [[ $AAA =~ ^[A-Z]+ ]] && echo 成立 || echo 不成立 成立 # 有+号,匹配一个或是多个,成立是因为匹配到了BB [root@shell ~]# [[ $AAA =~ ^[A-Z]+$ ]] && echo 成立 || echo 不成立 不成立 # 不成立是因为必须大写开头,中间大写相连,大写结尾 [root@shell ~]# AAA="BBAB" [root@shell ~]# [[ $AAA =~ ^[A-Z]+$ ]] && echo 成立 || echo 不成立 成立 [root@shell ~]# AAA="BBABabc" [root@shell ~]# [[ $AAA =~ ^[A-Za-z]+$ ]] && echo 成立 || echo 不成立 成立
案例1
传参不允许字符串为空
[root@shell /server/scripts]# cat hostname.sh #!/bin/bash #修改主机名称 read -p "输入主机名称: " name [ -z $name ] && echo "必须输入名称" && exit
案例2
脚本的手动退出,exit、q,为 $? 赋值
[root@shell /server/scripts]# cat ping.sh #!/bin/sh [ -f /etc/init.d/functions ] && . /etc/init.d/functions while true do read -p "请输入一个ip或url地址: " url [ $url = exit -o $url = q ] && exit ping -c1 -W1 $url &>/dev/null re=$? [ -z $url ] && echo "必须传一个url地址" && exit [ $re -eq 0 ] && action "ping $url is.." /bin/true || action "ping $url is.." /bin/false done
案例3
[root@shell ~]# cat name.sh #!/bin/sh read -p "请输入你的姓名:[A-Za-z] " name [[ ! $name =~ ^[A-Za-z]+$ ]] && echo "必须严格按照规范来写" && exit echo $name read -p "请输入你的年龄:[0-9] " age [[ ! $age =~ ^[0-9]+$ ]] && echo "必须严格按照规范来写你的年龄" && exit echo $age [root@shell ~]# sh name.sh 请输入你的姓名:[A-Za-z] mm mm 请输入你的年龄:[0-9] 100 100
5.本编总结:
子串知识:
子串切片 echo ${name:2:2}
子串长度统计 echo ${#name}
长度统计小于3的子串
for i in I am majunnan I am 18
do
[ ${#i} -lt 3 ] && echo $i
done
echo I am majunnan I am 18|xargs -n1|awk '{if(length<3)print }'
echo I am majunnan I am 18|awk '{for(i=1;i<=NF;i++)if(length($i)<3)print $i}'
子串删除 ## 贪婪匹配 %% 贪婪匹配
url=www.baidu.com
echo ${url#*.}
echo ${url%.*}
替换 /// 贪婪替换
echo ${url/www/news}
数值运算:
expr
$(())
$[]
let
bc
awk
条件表达式,取反加!
文件判断
-f -d -e -r -x -w
-d 判断目录
-f functions 函数库 action 输出 /bin/true /bin/false
条件表达式
整数比较,多整数比较 -o -a
-gt
-lt
-ge
-le
-ne
-eq
内存使用率
磁盘使用率
awk案例
字符串比对
[ "$USER" = "root" ]
-z 为空为真
-n 不为空则为真
正则比对
[[ $USER =~ ^r ]]
[[ $USER =~ ^[A-Za-z]+$ ]]
[[ $USER =~ ^[0-9]+$ ]]
——————————————————————————————————————————————————————————————————————————
无敌小马爱学习