一. 变量替换和测试
上图中 前4个是删除,后2个是替换
例子:
# 注意赋值时,"="左右不能有空格
[root@vermouth ~]$ variable_1="I love you, Do you love me"
[root@vermouth ~]$ var1=${variable_1#*ov}
[root@vermouth ~]$ echo $var1 # e you, Do you love me
[root@vermouth ~]$ var2=${variable_1#*ov}
[root@vermouth ~]$ echo $var2 # I love you, Do you love me
[root@vermouth ~]$ var3=${variable_1##*ov}
[root@vermouth ~]$ echo $var2 # e me
二. 字符串处理
2.1 计算字符串长度
- | 语法 | 说明 |
---|---|---|
方法一 | ${#string} | 无 |
方法二 | expr length “$string” | 必须加双引号(为了规范) |
[root@vermouth ~]$ var1="hello world"
[root@vermouth ~]$ echo ${#var1} # 11
[root@vermouth ~]$ echo `expr length "$var1"` # 11
2.2 获取字符串在字符串中的索引位置
语法 | 说明 |
---|---|
语法 | expr index “ s t r i n g " " string" " string""substring” |
[root@vermouth ~]$ var1="hello world"
[root@vermouth ~]$ echo `expr index "$var1" "o wo"` # 5,从1开始
[root@vermouth ~]$ echo `expr index "$var1" sadh` # 1,因为这是找字符的索引,也就是找"s","a","d","h"哪个先找到就返回哪个的索引,所以先找着"h",也就是返回 1
2.3 获取子串长度
语法 | 说明 |
---|---|
语法 | expr match “ s t r i n g " " string" " string""substring” |
[root@vermouth ~]$ var1="quickstart is a app"
[root@vermouth ~]$ echo `expr match "$var1" quick` # 5
[root@vermouth ~]$ echo `expr index "$var1" "app"` # 0,子串必须要从头开始匹配
index 和 match 用的都不多
2.4 抽取子串
[root@java ~]# var1=abcdefghijk
[root@java ~]#
[root@java ~]#
[root@java ~]# echo ${var1:(2)} # 最左边索引为0
cdefghijk
[root@java ~]# echo ${var1:(-2)} # 最右边索引为 -1
jk
[root@java ~]# echo ${var1: -2} # 冒号后有一个空格
jk
[root@java ~]# echo ${var1:2}
cdefghijk
[root@java ~]# echo ${var1:2:3}
cde
[root@java ~]# echo `expr substr "$var1" 2 3` # 最左边索引为1
bcd
2.5 总结
综上:
expr func ..
:最左边元素的索引是1${var:..}
:最左边元素的索引是0
三. 字符串处理完整脚本
3.1 需求
变量 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 则退出交互模式
3.2 思路分析
- 划分不同的功能模块,并编写函数
- function print_tips
- function len_of_string
- function del_hadoop
- function rep_hadoop_mapreduce_first
- function rep_hadoop_mapreduce_all
- 实现第一步所定义的功能函数
- 程序主流程的设计
3.3 代码
#!/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 "-----------------------------------------------"
}
# string的长度
function len_of_string
{
echo "***************************"
echo "${#string}"
echo "***************************"
}
# 删除所有Hadoop
function del_hadoop
{
echo "***************************"
echo "${string//Hadoop/}"
echo "***************************"
}
# 把第一个Hadoop替换为mapreduce
function rep_hadoop_mapreduce_first
{
echo "***************************"
echo "${string/Hadoop/mapreduce}"
echo "***************************"
}
# 把所有Hadoop替换为mapreduce
function rep_hadoop_mapreduce_all
{
echo "***************************"
echo "${string//Hadoop/mapreduce}"
echo "***************************"
}
while true
do
echo
echo "[string]=$string"
print_tips
read -p "Pls input your choice(1|2|3|4|q|Q): " choice
# echo $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
四. 命令替换
- | 语法格式 |
---|---|
方式一 | `comand` |
方式二 | $(command) |
4.1 举例
获取系统所有用户并输出
#!/bin/bash
# -d 分隔符 -f 指定field
# $(($index + 1)) 数学运算
index=1
for user in `cat /etc/passwd | cut -d ":" -f 1`
do
echo "This is $index user: $user"
index=$(($index + 1))
done
根据当前时间计算明年的年份
echo "Next year is $(($(date +%Y) + 1)) year"
根据系统时间获取今年还剩下多少星期,已经过了多少星期
# %j day of year
echo "This year has passed $(date +%j) days"
echo "This year has passed $(($(date +%j) / 7)) weeks"
# 这样其实是不对的,因为 $(date +%j) 的结果是0开头(比如049),但是 `$(())` 会把0开头的当作8进制,
判断nginx进程是否存在,若不存在则自动拉起该进程
#!/bin/bash
# wc -l 统计行号,具体可以看 man wc
# grep -v grep 把包含 grep 的那一行去掉
nginx_process_num=$(ps -ef | grep nginx | grep -v grep | wc -l)
if [ $nginx_process_num -eq 0 ];then
systemctl start nginx
fi
4.2 总结:
- `xx` 和
$(xx)
是等价的,推荐初学者使用 $(),易于掌握,但是极少数UNIX可能不支持 $((yy))
主要用于算术运算,包括加减乘除num1=50 num2=70 num3=$(($num1 + $num2)) # 120
五. 有类型变量
declare 和 typeset 命令
- declare 和 typeset 等价
- declare 和 typeset 都是用来定义变量类型
declre命令参数表:
参数 | 含义 |
---|---|
-r | 将变量设为只读 |
-i | 将变量设为整数 |
-a | 将变量设为数组 |
-f | 显示此脚本前定义过的所以函数及内容 |
-F | 仅显示此脚本前定义过的函数名 |
-x | 将变量声明为环境变量 |
num1=10
num2=$num1+20
echo $num2 # 10+20
declare -i num3
num3=$num1+20
echo $num3 # 30
5.1 数组
数组不常用,也不推荐使用
declare -a array
array=("java" "javascript" "python" "go")
echo ${array[@]} # java javascript python go
echo ${array[1]} # javascript
echo ${#array[@]} # 4 元素个数
echo ${#array[1]} # 10 javascript的长度
六. 数学运算
6.1 语法格式
- | 语法 |
---|---|
方法一 | expr $num1 operator $num2 |
方法二 | $(($num1 operator $num2)) |
6.2 expr 操作符对照表
# 操作符前后要加 “空格”
# ">" 需要转义,因为这个在linux中是重定向
a=1
b=6
expr $a\>$b # 1>6
expr $a \> $b # 0
expr 只能处理整数
6.3 例子
提示用户输入一个正整数,然后计算:1+2+…+num的值;必须对num是否为正整数做判断,不符合应当允许用户再次输入
#!/bin/bash
while true
do
read -p "pls input a positive number: " num
expr $num + 1 &> /dev/null # 判断num是否是整数
if [ $? -eq 0 ];then
if [ `expr $num \> 0` -eq 1 ];then # 判断num是否是正数
for((i=1;i<=$num;i++))
do
sum=`expr $sum + $i`
done
echo "1+2+..+$num=$sum"
exit
else
echo "不是正整数"
fi
else
echo "不是整数"
fi
done
6.4 bc
- bc是bash内建的运算器,支持浮点数运算
- 内建变量scale可以设置,默认为0
echo "10 + 20" | bc # 30
echo "scale=6;66.66 + 88.88" | bc #