1. 变量替换
语法 | 说明 |
---|---|
${变量名#匹配规则} | 从变量开头进行规则匹配,将符合最短的数据删除。 |
${变量名##匹配规则} | 从变量开头进行规则匹配,将符合最长的数据删除。 |
${变量名%匹配规则} | 从变量尾部进行规则匹配,将符合最短的数据删除。 |
${变量名%%匹配规则} | 从变量尾部进行规则匹配,将符合最长的数据删除。 |
${变量名/旧字符串/新字符串} | 变量内容符合旧字符串则,则第一个旧字符串会被新字符串取代。 |
${变量名//旧字符串/新字符串} | 变量内容符合旧字符串则,则全部的旧字符串会被新字符串取代。 |
例子1:
variable_1="I love you, Do you love me"
var1=${variable_1#*ov}
var2=${variable_1##*ov}
var3=${variable_1%ov*}
var4=${variable_1%%ov*}
echo $PATH
var5=${PATH/bin/BIN}
var6=${PATH//bin/BIN}
2. 变量测试
变量配置方式 | str没有配置 | str为空字符串 | str已配置且非空 |
---|---|---|---|
var=${str-expr} | var=expr | var= | var=$str |
var=${str:-expr} | var=expr | var=expr | var=$str |
var=${str+expr} | var= | var=expr | var=expr |
var=${str:+expr} | var= | var= | var=expr |
var=${str=expr} | var=expr | var= | var=$str |
var={str:=expr} | var=expr | var=expr | var=$str |
3. 字符串处理
3.1. 计算字符串长度
方法 | 语法 | 说明 |
---|---|---|
方法一 | ${#string} | 无 |
方法二 | expr length “$string” | string中有空格,则必须加双引号。 |
例子:
var1="Hello World"
#方法一
len=${#var1}
#方法二
len='expr length "$var1"'
echo $len #结果为11
3.2. 获取子串在字符串中的索引位置
语法 | expr index $string $substring |
---|
例子:
var1="quickstart is a app"
ind='expr index "$var1" start'
echo $ind #结果为6
ind='expr index "$var1" uniq'
echo $ind #结果为1
ind='expr index "$var1" cnk'
echo $ind #结果为4
3.3. 获取子串长度
语法 | expr match “$string” substr |
---|
例子:
var1="quickstart is a app"
sub_len= 'expr match "$var1" app'
echo $sub_len #结果为0
sub_len='expr match "$var1" quic'
echo $sub_len #结果为4
sub_len='expr match "$var1" quic.*'
echo $sub_len #结果为19
3.4. 抽取字符串中的子串
方法 | 语法 | 说明 |
---|---|---|
方法一 | ${string:position} | 从string中的position开始 |
方法二 | ${string:position:length} | 从position开始,匹配长度为length |
方法三 | ${string: -position} | 从右边开始匹配 |
方法四 | ${string:(position)} | 从左边开始匹配 |
方法五 | expr substr $string $position $length | 从position开始,匹配长度为length |
例子:
var1="kafka hadoop yarn mapreduce"
#方法一
substr_1=${var1:10}
echo $substr_1 #结果为op yarn mapreduce
#方法二
substr_2=${var1:10:5}
echo $substr_2 #结果为op ya
#方法三
substr_3=${var1: -5}
encho $substr_3 #结果为educe
substr_4=${var1:(-5)}
echo $substr_4 #结果为educe
substr_3=${var1: -5:2}
echo $substr_3 #结果为ed
#方法五
substr_5='expr substr "$var1" 10 5'
echo $substr_5 #结果为oop y
【注】:使用expr,索引计数是从1开始计算;使用${string:position},索引计数是从0开始计数。
4. 练习
需求描述:
变量string=“Bigdata process framework is Hadoop, Hadoop is an open source project” 执行脚本之后,打印输出string字符串变量,并给出用户以下选项:
- 打印string长度;
- 删除字符串中所有的Hadoop;
- 替换第一个Hadoop为Mapreduce;
- 替换全部Hadoop为Mapreduce;
用户输入数字1|2|3|4,可以执行对应项的功能;输入q|Q则退出交互模式。
思路分析:
- 将不同的功能模块划分,并编写函数;
function print_tips
function len_of_string
function del_hadoop
function rep_hadoop_mapreduce_first
function rep_hadoop_mapreduce_all
- 实现第一步所定义的功能函数
function print_tips
{
echo "******************************"
echo "1. 打印string长度"
echo "2. 删除字符串中所有的Hadoop"
echo "3. 替换第一个Hadoop为Mapreduce"
echo "4. 替换全部Hadoop为Mapreduce"
echo "******************************"
}
function len_of_string
{
echo "${#string}"
}
function del_hadoop
{
echo "${string//Hadoop/}"
}
function rep_hadoop_mapreduce_first
{
echo "${string/Hadoop/Mapreduce}"
}
function rep_hadoop_mapreduce_all
{
echo "${string//Hadoop/Mapreduce}"
}
- 程序主流程的设计
cd lesson/
cd 2.3
ll
vim example.sh
#############脚本文件内容##############
#!/bin/bash
#
string="Bigdata process framework is Hadoop, Hadoop is an open source project"
function print_tips
{
echo "******************************"
echo "1. 打印string长度"
echo "2. 删除字符串中所有的Hadoop"
echo "3. 替换第一个Hadoop为Mapreduce"
echo "4. 替换全部Hadoop为Mapreduce"
echo "******************************"
}
function len_of_string
{
echo "${#string}"
}
function del_hadoop
{
echo "${string//Hadoop/}"
}
function rep_hadoop_mapreduce_first
{
echo "${string/Hadoop/Mapreduce}"
}
function rep_hadoop_mapreduce_all
{
echo "${string//Hadoop/Mapreduce}"
}
while true
do
echo "【string=$string】"
echo
print_tips
read -p "Please input your choice(1|2|3|4|q|Q):" choice
case $choice in
1)
len_of_string
;;
2)
del_hadoop
;;
3)
rep_hadoop_mapreduce_first
;;
4)
rep_hadoop_mapreduce_all
;;
q|Q)
exit
;;
*)
echo "Error,input only in {1|2|3|4|q|Q}"
;;
esac
done
5. 命令替换
方法 | 语法格式 |
---|---|
方法一 | command |
方法二 | $(command) |
例子1:
获取系统的所有用户并输出
cat /etc/passwd | cut -d ":" -f 1
vim example_1.sh
##############脚本文件内容#################
#!/bin/bash
#
index=1
for user in `cat /etc/passwd | cut -d ":" -f 1`
do
echo "This is $index user: $user"
index=$(($index + 1))
done
例子2:
根据系统时间计算今年或明年
date
date +%Y #结果为当前系统时间的年份
#或者
echo "This is $(date +%Y) year" #结果为This is 2020 year
echo "This is $(($(date +%Y) + 1)) year" #结果为This is 2021 year
例子3:
根据系统时间获取今年还剩下多少星期,已经过了多少星期
vim example_2.sh
###########脚本文件内容#############
#!/bin/bash
#
echo "This year have passed $(date +%j) days"
echo "This year have passed $(($(date +%j)/7)) weeks"
echo "There is $((365 - $(date +%j))) days before new year"
echo "There is $(((365 - $(date +%j))/7)) weeks before new year"
###########脚本文件内容#############
#执行脚本
sh example_2.sh
例子4:
判定nginx进程是否存在,若不存在则自动拉起该进程
vim example_3.sh
###########脚本文件内容#############
#!/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可能不支持,但
都是支持的;- ( ( ) ) 主 要 用 来 进 行 整 数 运 算 , 包 括 加 减 乘 除 , 引 用 变 量 前 面 可 以 加 (())主要用来进行整数运算,包括加减乘除,引用变量前面可以加 (())主要用来进行整数运算,包括加减乘除,引用变量前面可以加,也可以不加$
$(( (100 + 30) /13 ))
num1=20;num2=30
((num++));
((num--))
$(($num1+$num2*2))
6. 有类型变量
6.1. declare 和 typeset 命令
- declare 命令和 typeset 命令两者等价;
- declare、typeset 命令都是用来定义变量类型的;
6.2. declare 命令参数表
参数 | 含义 |
---|---|
-r | 将变量设为只读 |
-i | 将变量设为整数 |
-a | 将变量定义为数组 |
-f | 显示此脚本前定义过的所有函数及内容 |
-F | 仅显示此脚本前定义过的函数名 |
-x | 将变量声明为环境变量 |
- declare -r #声明变量为只读类型
var2="hello python"
declare -r var2
var2="world" #-bash: var:readonly variable
- declare -i #声明变量类型为整型
num1=10
num2=$num1+20
echo $num2 #结果为10+20
expr $num1 + 10 #结果为20
declare -i num3
num3=$num1+90
echo $num3 #结果为100
- declare -f #在脚本中显示定义的函数和内容;
- declare -F #在脚本中显示定义的函数
- declare -a
declare -a array
array=("jones" "mike" "kobe" "jordan")
echo ${array[@]} #结果为jones mike kobe jordan
echo ${array[0]} #结果为jones
echo ${array[1]} #结果为mike
echo ${#array[@]} #结果为4
echo ${#array[0]} #结果为5
echo ${#array[1]} #结果为4
#输出数组内容:
echo ${array[@]} #输出全部内容
echo ${array[1]} #输出下标索引为1的内容
#获取数组长度:
echo ${#array} #数组元素个数
echo ${#array[2]} #数组内下标索引为2的元素长度
#给数组某个下标赋值:
array[0]="lily" #给数组下标索引为1的元素赋值为lily
array[20]="hanmeimei" #在数组尾部添加一个新元素
#删除元素:
unset array[2] #清除元素
unset array #清空整个数组
#分片访问:
${array[@]:1:4} #显示数组下标索引从1开始到3的3个元素,
#内容替换
${array[@]/an/AN} #将数组中所有元素内包含kobe的子串替换为mcg
#数组遍历
for v in ${array[@]}
do
echo $v
done
- declare -x #声明为环境变量,可以在脚本中直接使用
num5=30
echo $num5 #结果为30
vim test1.sh
###############脚本文件内容#################
#!/bin/bash
#
echo $num5
###############脚本文件内容#################
sh test1.sh #结果为""
declare -x num5
sh test1.sh #结果为30
- 取消声明的变量:
- declare +r
- declare +i
- declare +a
- declare +X
7. Bash数学运算之expr
方法 | 语法 |
---|---|
方法一 | expr $num1 operator $num2 |
方法二 | ( ( (( ((num1 operator $num2)) |
expr操作符对照表
操作符 | 含义 |
---|---|
num1|num2 | num1不为空且非0,返回num1;否则返回num2 |
num1 & num2 | num1不为空且非0,返回num1;否则返回0 |
num1 < num2 | num1小于num2,返回1;否则返回0 |
num1 <= num2 | num1小于等于num2,返回1;否则返回0 |
num1 = num2 | num1等于num2,返回1;否则返回0 |
num1 != num2 | num1不等于num2,返回1;否则返回0 |
num1 > num2 | num1大于num2,返回1;否则返回0 |
num1 >= num2 | num1大于等于num2,返回1;否则返回0 |
num1 + num2 | 求和 |
num1 - num2 | 求差 |
num1 * num2 | 求积 |
num1 / num2 | 求商 |
num1 % num2 | 求余 |
bash数学运算只expr:
num1=30
num2=50
expr $num1 \> $num2 #结果为0
expr $num1 \< $num2 #结果为1
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
num1=17
num2=5
expr $num1 / $num2 #结果为3
num3=$(($num1+num2))
echo $num3 #结果为22
num3=$(($num1*$num2)) #该方法最好不要用来比较变量之间的大小,判断相等的时候会出现问题
echo $num3 #结果为85
练习例子:
提示用户输入一个正整数num,然后计算1+2+3+…+num的值;必须对num是否为正整数做判断,不符合应当允许再次输入。
#判断变量是否为正整数
vim sum.sh
#############脚本文件内容###############
#!/bin/bash
#
while true
do
read -p "please input a positive number: " num
expr $num + 1 &> /dev/null
if [ $? -eq 0 ];then
if [ `expr $num \> 0` -eq 1 ];then
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
8. Bash数学运算之bc
8.1. bc介绍
- bc是bash内建的运算器,支持浮点数运算;
- 内建变量scale可以设置,默认为0(不保留小数);
8.2. bc操作符对照表
操作符 | 含义 |
---|---|
num1 + num2 | 求和 |
num1 - num2 | 求差 |
num1 * num2 | 求积 |
num1 / num2 | 求商 |
num1 % num2 | 求余 |
num1 ^ num2 | 指数运算 |
which bc #结果为/usr/bin/bc
bc #显示bc版本号,版权等相关信息,然后就可以开始运算了
23 + 5 #结果为28
23 / 5 #结果为4
scale=2 #保留两位小数
23 / 5 #结果为4.60
#脚本中使用bc
echo "23+35" | bc #结果为58
echo "23.3+35" | bc #结果为58.3
echo "scale=4;23.3/3.5" | bc #结果为6.6571
vim bc.sh
#######脚本文件内容#########
#!/bin/bash
#
read -p "num1: " num1
read -p "num2: " num2
num3=`echo "scale=4;$num1*$num2" | bc`
echo "$num1 / $num2 = $num3"