第一课 Shell脚本编程-变量的高级用法
文章目录
第一节 变量的替换和测试
variable_1="I love you,Do you love me"
echo ${variable_1}
# 从头部开始匹配删除 删除第一个ov 前的所有内容
var1=${variable_1#*ov}
echo $var1 # e you,Do you love me
# 从头部开始匹配删除 删除最后一个ov 前的所有内容
var2=${variable_1##*ov}
echo $var2 # e me
# 从尾部开始匹配删除 删除第一个ov 前的所有内容
var3=${variable_1%ov*}
echo $var3 # I love you,Do you l
# 从尾部开始匹配删除 删除最后一个ov 前的所有内容
var4=${variable_1%%ov*}
echo $var4 # I l
# 第一个匹配替换
var5=${PATH/bin/Bin}
echo $var5
# 所有的匹配都替换
var6=${PATH//bin/Bin}
echo $var6
- 变量测试,如果没有配置或者为空或者配置了时候的赋值规则。
第二节 字符串常用操作
- 计算字符串长度
- 方法一:
${#string}
- 方法二:
expr length $string
- 方法一:
var1="Hello world"
# 方法一
len=${#var1}
echo ${len}
# 方法二 加上"" shell的语法并不是很规范
len=`expr length "$string"
echo ${len}
- 获取子串在字符串中的索引位置。语法:
expr index $string $substring
,实际上它会把子串切成一个个字符去找,先匹配上返回位置。
# 实际上返回s的位置
var1="quickstart is a app"
ind=`expr index "var1" start`
echo $ind # 6 从1开始数
# 实际上返回u的位置
ind=`expr index "var1" uniq`
echo $ind # 1 从1开始数
- 获取子串长度(用的不多)。从头开始匹配。
expr match $string $substring
var="quickstart is a app"
# expr match 必须从头就开始匹配
sub_len=`expr match "$var" quic`
echo $sub_len # 4
# expr match 必须中间匹配就找不到
sub_len=`expr match "$var" app`
echo $sub_len # 0
# expr match 可以有正则
sub_len=`expr match "$var" quic.*`
echo $sub_len # 19
- 抽取子串, 抽取字符串中的子串
- 方法一: s t r i n g : p o s i t i o n 或者 {string:position}或者 string:position或者{string:position : length }或者 s t r i n g : − p o s i t i o n 或者 {string: -position}或者 string:−position或者{string: (position) }
- 方法二:
expr substr $string $position $length
# 第一种方式
var1="kafka hadoop yarn mapreduce"
substr1=${var1:10} # 获取var1从第十个位置一直到最后
echo $substr1
substr1=${var1:10:5} # 获取var1从第十个位置 只提取5位
echo $substr1 # op ya
substr1=${var1: -5} # 获取右边数第五位一直到最后
echo $substr1 # educe
substr1=${var1: (-5)}
echo $substr1 # educe
substr1=${var1: -5:2} # 从-5开始取两个值
echo $substr1 # ed
# 第二种方式
substr1=`expr substr "$var1" 10 5` # 从第十个位置开始提取 提取五个
echo $substr1 # oop y
第三节 命令替换
- 方法一: `command`
- 方法二:
$ (comnand)
# 案例一: 获取系统得所有用户并输出
cat /etc/passwd # 第一列就是
man cut # 这里使用cut 指定分割符的方式
cat /etc/passwd | cut -d ":" -f 1 # -d指定分割符 -f取分割后的第一列
# 案例二: 根据系统时间计算今年或明年
echo "This is $(($(date +%Y)+1)) year" # (()) 代表算数运算 ()是命令替换
# 案例三: 根据系统时间获取今年还剩下多少星期,已经过了多少星期
man date # 查看使用
date +%j # j 表示今天是今年365天中第几天
echo $(($(date +%j)/7)) # 今年已经过了多少星期
echo $(((365-$(date +%j))/7)) # 今年还剩多少星期
# 案例四: 判定nginx进程是否存在,若不存在则自动拉起该进
ps -ef | grep nginx | grep -v grep | wc -l # 不包括grep中的nginx wc -l 统计行数
#!/bin/bash
nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_process_num -eq 0 ] ;then
systemctl start nginx
fi
- ``和
$()
两者是等价的,但推荐初学者使用$()
,易于掌握;缺点是极少数UNIX可能不支持。 (())
主要用来进行整数运算,包括加减乘除。引用变量前面可以加 ,也可以不加 ,也可以不加 ,也可以不加
echo $(((100 + 30) / 13 ))
num1=20 ; num2=30
((num++))
((num--))
$(($num1+$num2*2))
第四节 有类型变量
- declare命令和typeset命令两者等价
- declare、typeset命令都是用来定义变量类型的
# 声明只读变量
var1="hello world"
declare -r var1
echo $var1
# var1="hello python" # 修改报错 只读变量 -bash: var1: 只读变量
num1=10
num2=$num1+20
echo $num2 # 10+20 没有声明类型 默认shell把它当字符串处理
expr $num1 + 20 # 这是直接运算
declare -i num3 # 声明num3为整形变量
num3=$num1+90
echo $num3 # 30
declare -f # 可以列出系统中可用的函数名 函数内容
declare -F # 可以列出系统中可用的函数名
declare -a array # 声明一个数组
array=("jones" "mike" "kobe" "jordan")
# 输出全部内容:
echo ${array[@]}
# 输出下标索引为1的内容
echo ${array[1]}
# 获取数组长度,数组内元素个数:
echo ${#array[@]}
# 数组内下标索引为2的元素长度
echo ${#array[2]}
# 给数组某个下标赋值, 给数组下标索引为1的元素赋值为1ily:
array[0]="1ily"
# 在数组尾部添加一个新元素
array[20]="hanmeimei"
# 清除元素:
unset array[2]
# 清空整个数组
unset array
# 分片访问,显示数组下标索引从1开始到3的3个元素,不显:
${array[@]:1:4}
# 内容替换,将数组中所有元素内包含kobe的子串替换为mcg:
${array[@]/an/AN}
# 数组遍历:
for v in ${array[@]}
do
echo $v
done
num5=10
declare -x num5 # 声明num5为环境变量
# 取消声明的变量:
declare +r
declare +i
declare +a
declare +x
第五节 Bash数学运算expr-整型
- 方法一:
expr $num1 operator $num2
- 方法二:
$(($num1 operator $num2))
- 经验:比较用expr,而不使用
$(())
。因为容易出错。
# 这里管道符号必须转义
num1=20
num2=100
expr $num1 \| $num2
expr $num1 \& $num2
expr $num1 \< $num2
expr $num1 \< $num2
expr $num1 \<= $num2
expr $num1 \> $num2
expr $num1 \>= $num2
expr $num1 = $num2
expr $num1 != $num2
expr $num1 + $num2
expr $num1 - $num2
expr $num1 \*$num2
expr $num1 / $num2
expr $num1 % $num2
# 不能直接输出 必须赋值
num3=$(($num1+$num2))
- 案例:提示用户输入一个正整数num,然后计算1+2+3+…+num的值;必须对num是否为正整数做判断,不符合重新输入。
#!/bin/bash
# expr 40.11 + 1 小数加1会报错expr: 非整数参数
while true
do
read -p "pls input a positive number: " num
expr $num + 1 &> /dev/null # 计算的结果不想输出到终端 丢到垃圾桶里
if [ $? -eq 0 ];then
if [ `expr $num \> 0` -eq 1 ];then
echo "Yes ,Positv number"
for((i=1;i<=$num;i++))
do
sum=`expr $sum +$i`
done
echo "1+2+3+...+$num=$sum"
exit
fi
fi
echo "error, input unlegal"
continue
done
第六节 Bash数学运算bc-浮点数运算
- bc是bash内建的运算器,支持浮点数运算
- 内建变量scale可以设置,默认为0
which bc
# 直接bc回车 交互使用
bc
[root@localhost ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
23 + 5
28
12.23 * 3
36.69
12 / 3
4
12.12 / 11
1
scale=2 # 设置精确度
12.12 / 11
1.10
# 脚本中使用 通过管道传给bc
echo "23+35" | bc
echo "scal2=2;23.12 * 3" | bc