02Shell的变量运算以及数据比较
变量切片
使用awk取值
[root@laoli day2]# echo $name|awk -F 'I' '{print $2}'am laoli[root@laoli day2]# echo $name|awk '{print $2,$3}'
am laoli
变量切片:分割方式
从name的第三个字符开始(索引从0开始),取到结尾
[root@laoli day2]# echo ${name:2}
am laoli从name的第三个字符开始(索引从0开始),往后取两个字符
[root@laoli day2]# echo ${name:2:2}
am
统计变量字串字符串的长度
${#name}
:
Shell 内置的变量长度计算方式,直接返回变量name
中字符的实际数量(包含空格),结果为 10。echo $name|wc -L
:wc -L
用于计算输入中最长行的长度。这里$name
未加引号但内容无特殊字符,输出完整字符串后,wc -L
返回其长度 10。expr length '$name'
:
单引号会将$name
视为普通字符串(而非变量),实际计算的是字符串$name
的长度($
、n
、a
、m
、e
共 5 个字符),所以结果为 5。expr length "$name"
:
双引号会正确解析变量name
,expr length
计算其实际内容的长度,结果为 10。echo $name|awk '{print length}'
:awk
的length
函数计算当前行的字符数,由于$name
内容被完整输出,结果为 10。
[root@laoli day2]# echo ${#name}
10
[root@laoli day2]# echo $name|wc -L
10
[root@laoli day2]# expr length '$name'
5
[root@laoli day2]# expr length "$name"
10
[root@laoli day2]# echo $name|awk '{print length}'
10
统计出小于3的字符串
方法一:使用awk+if判断
[root@laoli day2]# echo $name|xargs -n1|awk '{if(length<3) print}'
I
am方法二:使用for循环
-lt 代表less than,少于
-gt 大于(greater than)[root@laoli day2]# cat count.sh
#!/bin/bash
for i in I am laoli
do[ ${#i} -lt 3 ]&&echo $i
done
[root@laoli day2]# . count.sh
I
amsh -x显示执行过程
[root@laoli day2]# sh -x count.sh
+ for i in I am laoli
+ '[' 1 -lt 3 ']'
+ echo I
I
+ for i in I am laoli
+ '[' 2 -lt 3 ']'
+ echo am
am
+ for i in I am laoli
+ '[' 5 -lt 3 ']'方法三:for循环遍历
[root@laoli day2]# echo $name|awk '{for(i=1;i<NF;i++)if(length($i)<3)print $i}'
I
am
变量字串的删除
#从前往后匹配删除
##从前往后贪婪匹配删除
% 从后面匹配删除
%% 从后贪婪匹配删除
[root@laoli day2]# name=www.baidu.com
方法一:
[root@laoli day2]# echo ${name#www.} 删除www.
baidu.com
[root@laoli day2]# echo ${name#*.} 删除.前面所有的字符包括.
baidu.com
[root@laoli day2]# echo ${name#w*u} 从w删到u
.com
[root@laoli day2]# echo ${name##*.} 贪婪匹配,删除最后一个.前面的所有字符包括.
com
[root@laoli day2]# echo ${name%.com} 从后面开始删,删除.com
www.baidu
[root@laoli day2]# echo ${name%.*} 从后面开始删,删除.后面所有的字符包括.
www.baidu
[root@laoli day2]# echo ${name%%.*} 反向贪婪匹配,删除最前面一个.到结束所有字符包括.
www方法二:
[root@laoli day2]# echo $name|awk -F '.' '{print $2"."$3}'
baidu.com
双引号(".")主要作用是 明确表示一个独立的字符串常量(小数点字符),避免其被 awk 语法解析为其他含义方法三:
[root@laoli day2]# echo $name|awk -F 'w.' '{print $3}'
baidu.com获取磁盘使用率
[root@laoli day2]# use_disk=`df -h|awk 'NR==7{print $5}'`
[root@laoli day2]# echo $use_disk
37%
[root@laoli day2]# echo ${use_disk%\%}
37#语法冲突用撬棍\
数值运算expr
[root@laoli day2]# expr 1+1=
1+1=
[root@laoli day2]# expr 1 + 1
2
[root@laoli day2]# expr 1 /1
expr: 语法错误
[root@laoli day2]# expr 1 / 1
1
[root@laoli day2]# expr 3 % 2
1
[root@laoli day2]# expr 3 % 1
0
[root@laoli day2]# expr 3 % 3
0
[root@laoli day2]# expr 3 % 4
3案例: 判断用户传参是否为数字,成功为0,失败不为0
[root@laoli day2]# expr x + y
expr: 非整数参数
[root@laoli day2]# echo $?
2[root@laoli day2]# cat expr.sh
#!/bin/bash
#判断传入的参数是否为数字整数
read -p 'Please Input name:' name
read -p 'Please Input age:' age
expr 1 + $age &>/dev/null
[ $? -ne 0 ]&&echo '请输入正确的年龄'&&exit
echo name:$name
echo age:$age
$(()) 整数运算
$(()) 运算中最常用的计算方式,效率是最高的
[root@laoli day2]# echo $((1 + 1))
2
[root@laoli day2]# echo $((3%2))
1
[root@laoli day2]# echo $((3%2*3))
3
$[]整数运算
$[]运算规则和$(())差不多,但是后者兼容性更强,所以平时几乎都是用后者
[root@laoli day2]# echo $[1+3]
4
[root@laoli day2]# echo $[1*3]
3
[root@laoli day2]# echo $[8%3]
2
所有的运算都支持变量
[root@laoli day2]# a=10
[root@laoli day2]# b=20
[root@laoli day2]# echo $((a+b))
30
[root@laoli day2]# echo $((a-b))
-10
[root@laoli day2]# echo $((a%b))
10
[root@laoli day2]# echo $((a%b-a*b-3))
-193
[root@laoli day2]# echo $[a+b+3]
33
[root@laoli day2]# echo $[a*b+3]
203
let运算
let
命令特点:
- 直接操作变量,不需要使用
$
符号引用变量 - 可以执行多个表达式(用逗号分隔)
- 运算结果会直接赋值给变量
- 执行成功返回 0 状态码,失败返回非 0 状态码
[root@laoli day2]# a=10
[root@laoli day2]# let a++
[root@laoli day2]# echo $a
11
[root@laoli day2]# let i++
[root@laoli day2]# echo $i
1
[root@laoli day2]# let i++
[root@laoli day2]# echo $i
2
[root@laoli day2]# let i--
[root@laoli day2]# echo $i
1
[root@laoli day2]# let a=a++
[root@laoli day2]# echo $a
11案例: 用let i++ 统计 循环的次数
[root@laoli day2]# cat let.sh
#!/bin/bash
for i in I am laoli
doecho $ilet a++
done
echo $a[root@laoli day2]# sh let.sh
I
am
laoli
3unset取消变量
[root@laoli day2]# echo $i
1
[root@laoli day2]# unset i
[root@laoli day2]# echo $i++1是变量先自加1再参加运算
[root@laoli day2]# a=1
[root@laoli day2]# let c=++a
[root@laoli day2]# echo $c
2
[root@laoli day2]# echo $a
2
bc运算
bc运算特点:
支持整数和浮点数运算
相比 $(())
、let
等内置方法,bc
是外部命令,运算效率稍低
[root@laoli day2]# echo 10+10|bc
20
[root@laoli day2]# echo 1+10|bc
11
[root@laoli day2]# echo 12*10|bc
120
[root@laoli day2]# echo 12*10%3|bc
0
awk运算 支持小数和整数
在 Bash 脚本中,可以调用 Python 来进行运算,这对于处理复杂计算或需要更高精度的场景非常有用。Python 支持整数、浮点数、复数等多种数值类型,以及丰富的数学运算。
直接传参
[root@laoli day2]# cat count.sh
#!/bin/bash
[ $# -ne 2 ]&&echo '请输入俩参数'&&exit 1expr $1 + $2 &>/dev/null
[ $? -ne 0 ]&&echo '请输入整数'&&exit 2echo $1 + $2 = $[$1 + $2]
echo $1 - $2 = $[$1 - $2]
echo $1 / $2 = $[$1 / $2]
echo $1 \* $2 = $[$1 * $2][root@laoli day2]# sh count.sh 1 4
1 + 4 = 5
1 - 4 = -3
1 / 4 = 0
1 * 4 = 4
条件表达式
[ -f 文件名称 ] # 判断普通文件是否存在 表达式成立 常用
[ -d 目录名称 ] # 判断目录是否存在 常用
[ -e 文件名称 ] # 文件存在即为真(表达式成立) 不分类型
[ -r 文件名称 ] # 拥有可读权限则为真
[ -w 文件名称 ] # 拥有可写权限则为真
[ -x 文件名称 ] # 拥有可执行权限则为真
[ ! -f 文件名称 ] # 对表达式取反
[root@laoli day2]# [ -f count.sh ]&&echo yes
yes
[root@laoli day2]# [ -d ../day2/ ]&&echo yes
yes
[root@laoli day2]# [ -e count.sh ]&&echo yes
yes
[root@laoli day2]# [ -r count.sh ]&&echo yes
yes
[root@laoli day2]# [ -r count.sh ]&&echo yes||echo no
yes
[root@laoli day2]# [ -r count.shs ]&&echo yes||echo no
no
[root@laoli day2]# [ -w count.shs ]&&echo yes||echo no
no
[root@laoli day2]# [ -w count.sh ]&&echo yes||echo no
yes
[root@laoli day2]# [ -x count.sh ]&&echo yes||echo no
no[root@laoli day2]# [ ! -x count.shs ]&&echo yes||echo no
yes
并且关系 -a and
或者关系 -o or
[root@laoli day2]# [ -f count.sh -a -f expr.sh ]&&echo yes
yes
[root@laoli day2]# [ -f count.sh -a -f expr.shs ]&&echo yes||echo no
no
[root@laoli day2]# [ -f count.s -o -f expr.sh ]&&echo yes||echo no
yes
案例1.判断目录是否存在如果存在则继续往下执行,如果不存在则创建
[root@laoli day2]# cat test.sh
#!bin/bash
[ -d /data ]||mkdir /data
cd /data
touch 1.txt案例: 判断文件是否存在,如果存在则执行
[root@laoli day2]# cat 1.sh
#!/bin/bash
name=hehe
[root@laoli day2]# cat 2.sh
#!/bin/bash
[ -f /root/shell/day02/1.sh ]&&sh /root/shell/dat02/1.sh
touch /data/2.txt
字符串比对
语法结构: [ 字符串1 表达式 字符串2 ]
-z 变量为空成立
-n 变量不为空成立
[root@localhost day02]#[ "root" = "$SHELL" ] && echo 成立 || echo 不成立
不成立
[root@localhost day02]#[ "/bin/bash" = "$SHELL" ] && echo 成立 || echo 不成立
成立[root@localhost day02]# [ -z $SHELL ]&&echo yes||echo no
no
[root@localhost day02]# [ -n $SHELL ]&&echo yes||echo no
yes案例: 判断字符串传参不能为空
[root@localhost day02]# cat name.sh
#!/bin/bash
read -p 'input yourname :' name
Lt=`echo $name|sed -r 's#[^0-9]##g'|wc -L`
[ $Lt -ne 0 ]&&echo 'num is error'&&exit[ -z $name ]&&echo 'error'&&exitread -p 'input your age:' age
expr 1 + $age &>/dev/null
[ $? -ne 0 ]&&echo 'error'&&exit
echo name:$name
echo age:$age
[root@localhost day02]# sh name.sh
input yourname :laoli
input your age:32
name:laoli
age:32
正则比对
正则判断要用双中括号[[ ]]
! 取反
[root@localhost day02]# [[ root =~ ^r ]]&&echo yes||echo no
yes
[root@localhost day02]# [[ root =~ t$ ]]&&echo yes||echo no
yes
[root@localhost day02]# [[ root =~ ^a ]]&&echo yes||echo no
no
[root@localhost day02]# [[ 2root =~ ^2 ]]&&echo yes||echo no
yes
[root@localhost day02]# [[ 2root2 =~ ^2$ ]]&&echo yes||echo no
no
[root@localhost day02]# [[ root32 =~ ^[0-9] ]]&&echo yes||echo no
no
[root@localhost day02]# [[ 32root32 =~ ^[0-9]$ ]]&&echo yes||echo no
no
[root@localhost day02]# [[ 3232 =~ ^[0-9]$ ]]&&echo yes||echo no
no
[root@localhost day02]# [[ 3232 =~ ^[0-9] ]]&&echo yes||echo no
yes
[root@localhost day02]# [[ 3232 =~ ^[0-9]$ ]]&&echo yes||echo no
no
[root@localhost day02]# [[ 3232 =~ ^[0-9]+$ ]]&&echo yes||echo no
yes案例: 判断用户传入的参数必须为字符串
[root@localhost day02]# cat panduan.sh
#!/bin/bash
read -p 'input your name:' name
[[ ! $name =~ ^[a-z]+$ ]]&&echo 'error'&&exit
echo $name is string案例: 判断用户传入的参数必须为纯数字
[root@localhost day02]# cat panduan01.sh
#!/bin/bash
read -p 'input your age:' age
[[ ! $age =~ ^[0-9]+$ ]]&&echo 'error'&&exit
echo $age is num
数字比较:
语法结构: [ 整数1 比较符 整数2 ]
表达式:
-eq 相等
-ne 不等于
-gt 大于
-ge 大于或者等于
-lt 小于 -le 小于等于
[root@localhost day02]# [ 10 -eq 10 ]&&echo yes||echo no
yes
[root@localhost day02]# [ 10 -eq 0 ]&&echo yes||echo no
no
[root@localhost day02]# [ ! 10 -eq 0 ]&&echo yes||echo no
yes
[root@localhost day02]# [ 10 -lt 0 ]&&echo yes||echo no
no
[root@localhost day02]# [ 10 -gt 0 ]&&echo yes||echo no
yes
[root@localhost day02]# [ 10 -lt 0 -o 10 -gt 0 ]&&echo yes||echo no
yes
[root@localhost day02]# [ 10 -lt 0 -a 10 -gt 0 ]&&echo yes||echo no
no
[root@localhost day02]# [ 10 -gt 0 -a 0 -lt 10 ]&&echo yes||echo no
yes
这是我的个人学习笔记,主要用于记录自己对知识点的理解和梳理。由于目前仍在学习探索阶段,内容中难免存在理解偏差或表述疏漏,恳请各位大佬不吝赐教,多提宝贵意见~ 若有不同看法,欢迎理性交流探讨,感谢包容与指正!