Shell编程入门--变量

变量

  • 1.变量类型
    • 1.1.预定义变量
    • 1.2.环境变量
    • 1.3.自定义变量
    • 1.4.位置变量
  • 2.变量运算
    • 2.1.基础运算
    • 2.2.浮点运算
    • 2.3.随机数
  • 3.变量引用
    • 3.1.转义
    • 3.2.读取用户标准输入read
    • 3.3.花里胡哨的echo
  • 4.变量置换
    • 4.1.命令替换
    • 4.2.变量替换
    • 4.3.变量替换——匹配截取
    • 4.4.basename && dirname

变量:bash作为程序设计语言和其它高级语言一样也提供使用和定义变量的功能;简单说就是让一个特定的字符串代表不固定的内容

1.变量类型

1.1.预定义变量

预定义变量:预定义的特殊变量有着特殊的含义,用户不可以更改,所有的预定义变量都由$符号和另外一个符号组成,常用的预定义特殊变量如下:
$$ 当前进程PID
$? 命令执行后的返回状态为 0 则执行正确,非 0 为执行错误
$# 位置参数的数量
$* 所有位置参数的内容
$@ 显示所有的参数
$! 上一个后台进程的PID (wait命令中使用,后面讲)

[root@localhost ~]# vim test.sh
    //ping百度和京东脚本
#!/bin/bash
echo "number of arguments:$#"    #位置参数的数量为:$#预定义变量
for a in $@ ; do
    ping -c2 -w2 $a
done

//运行脚本并往脚本内传参
[root@localhost ~]# bash test.sh baidu.com  jd.com    //jd.com/baidu.com就是参数
number of arguments:2        //总共有2个位置参数
PING baidu.com (110.242.68.66) 56(84) bytes of data.
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=1 ttl=128 time=71.6 ms
64 bytes from 110.242.68.66 (110.242.68.66): icmp_seq=2 ttl=128 time=57.5 ms

--- baidu.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 57.533/64.571/71.609/7.038 ms

PING jd.com (111.13.149.108) 56(84) bytes of data.
64 bytes from 111.13.149.108 (111.13.149.108): icmp_seq=1 ttl=128 time=60.6 ms
64 bytes from 111.13.149.108 (111.13.149.108): icmp_seq=2 ttl=128 time=64.6 ms

--- jd.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 60.610/62.629/64.649/2.034 ms


拓展:$* 和 $@ 有什么区别
$* : 作为一个整体扩展所有参数
$@ : 将每个参数分别扩展
在需要单独处理每个参数时使用 $@
在需要将所有参数作为一个整体时使用 $*
//例如:
function test {
  for i in "$*"; do 
     echo $i; 
  done

  for i in "$@" ; do 
     echo $i;
  done
} 

test 1 2 3
//执行结果
1 2 3        $*运行的结果,将值看成一个整体
1        $@运行的结果,将值看成单独的每一个参数            
2
3


[root@localhost ~]# echo $?    //最后一次执行的命令的返回状态。如果这个变量的值为 0,则证明上一条命令正确执行;如果这个变量的值为非 0 ,则 证明上一条命令执行错误
[root@localhost ~]# echo $$    //当前进程的进程号(PID)
[root@localhost ~]# echo $!    //后台运行的最后一个进程的进程号(PID)

[root@localhost ~]# ls
anaconda-ks.cfg  a.txt  b.txt  file.out  helloworld.sh  //ls命令正确执行
[root@localhost ~]# echo $?
0
//预定义变量"$?"的值是0,证明上一条命令正确执

//输出当前进程的PID
[root@localhost ~]# vim variable.sh
#!/bin/bash
echo "The current process is $$"
[root@localhost ~]# sh variable.sh 
The current process is 1416 
 
//这个PID就是variable.sh脚本执行时生成的进程的PID

[root@localhost ~]# sleep 30 &    
//符号"&"的意思是把命令放入后台执行
[1] 1418  
[root@localhost ~]# echo $!
1418

1.2.环境变量

环境变量:shell在开始执行时已经定义好的,就是系统执行环境的一些设置
env 是 environment (环境) 的简写,所有的环境变量(包含自定义的环境变量)
set 列出系统中所有的变量,包括自定义的变量
export 变量名【使自定义的变量成为环境变量】,才使用这个参数。
环境变量拥有可继承性:export之后就拥有继承性环境变量可以被向下继承

[root@localhost ~]# a=12
[root@localhost ~]# export a
[root@localhost ~]# echo $a
12
[root@localhost ~]# bash        //再开一个子shell
[root@localhost ~]# echo $a        //向下继承
12

//临时生效
[root@localhost ~]# IPADDR=192.168.1.1
[root@localhost ~]# echo $IPADDR
192.168.1.1

//永久生效
//写到4个登陆脚本中 ~/.bashrc ~/.bash_profile 更好放在/etc/profile.d/目录下建立独立的环境变量配置文件
[root@localhost ~]# vim /etc/profile.d/test.sh
IPADDR=192.168.1.1
[root@localhost ~]# source /etc/profile.d/test.sh  //让环境变量生效
[root@localhost ~]# echo $IPADDT
192.168.1.1

//常用环境变量:USER UID HOME HOSTNAME PWD PS1 PATH
//PATH:存储所有命令所在的路径

1.3.自定义变量

自定义变量:就是自己设置的变量只能在【当前终端和脚本中】使用
变量名称=值
变量名称:只能由【字母、数字、下划线】组成,不能以【数字】开头,也不能有【敏感符号】
注意:应该让变量名称有意义;
例如:INSTALL_DIR=‘/usr/local/mysql’
    = 赋值符号 前后不能有空格 ;
    值:所有的字符串和数字都可以;
    引用变量:$变量名 或 ${变量名}。
查看变量: echo $变量名
取消变量: unset 变量名,仅在当前shell中有效

[root@localhost ~]# 123abc=aaa
-bash: 123abc=aaa: 未找到命令
[root@localhost ~]# abc123=aaa
[root@localhost ~]# echo $abc123
aaa
[root@localhost ~]# $ABC123=aaa    //敏感字符
-bash: =aaa: 未找到命令

[root@localhost ~]# a=100
[root@localhost ~]# echo $a
100
[root@localhost ~]# echo $aa     //这里输出为空,因为解释器认为$aa是变量
[root@localhost ~]# echo ${a}a
100a

[root@localhost ~]# a=12
[root@localhost ~]# echo $a
12
[root@localhost ~]# unset a
[root@localhost ~]# echo $a

继承

子shell 仅仅只会继承当前父shell 的环境变量, 不会继承父 shell 的【自定义变量】
还有:只能往下继承,而不能影响上面父shell的变量

[root@localhost ~]# a=1
[root@localhost ~]# b=2
[root@localhost ~]# export b
[root@localhost ~]# echo $b
2
[root@localhost ~]# echo $a
1
[root@localhost ~]# bash    //子shell
[root@localhost ~]# echo $b
2
[root@localhost ~]# echo $a

//shell会向下继承,不会向上继承
[root@localhost ~]# bash            //打开一个子shell
[root@localhost ~]# export a=hello  //在子shell声明一个环境变量
[root@localhost ~]# bash            //在子shell中再打开一个子shell
[root@localhost ~]# echo $a         //变量可以生效
hello
[root@localhost ~]# exit            //退出子shell的子shell
exit
[root@localhost ~]# exit            //退出子shell
exit
[root@localhost ~]# echo $a         //在当前父shell中,其子shell声明的环境变量是无效的

1.4.位置变量

位置变量也叫位置参数:在脚本代码中调用通过命令行传递给脚本的参数
$1 $2 $3 $…… $n 分别对应传递给脚本内容里面的第1、第2等参数
适用场景:应用程序启动/停止/重启脚本、添加用户时,指定用户名、密码、用户组等
例子:
bash test.sh start ----start是第1个位置参数
bash test.sh 2 3 5 hello ----2是第1个位置参数,3是第2个位置参数…依次类推

例子1:位置参数
[root@localhost ~]# cd /opt/test/script/
[root@localhost script]# vim weizhi.sh
#!/usr/bin/bash
echo 我的第一个位置参数是:$1 
echo 我的第二个位置参数是:$2 
echo 我的第三个位置参数是:$3 
echo 我的第四个位置参数是:$4 
echo 一共有 $# 个位置参数 
echo 你输入的参数分别是:$*
[root@localhost script]# sh weizhi.sh 1 3 4 5
我的第一个位置参数是:1
我的第二个位置参数是:3
我的第三个位置参数是:4
我的第四个位置参数是:5
一共有 4 个位置参数
你输入的参数分别是:1 3 4 5

例子2:创建用户、创建用户组并设置用户密码
[root@localhost ~]# vim adduser.sh
#!/bin/sh
groupadd $1
useradd -g $1 $2 && echo $3 |passwd --stdin $2
echo "用户组为:$1;用户名为:$2;用户名密码为:$3"

[root@localhost ~]# sh adduser.sh  qf2302 liangzai  liangzai
更改用户 liangzai 的密码 。
passwd:所有的身份验证令牌已经成功更新。
用户组为:qf2302;用户名为:liangzai;用户名密码为:liangzai

练习1

//编写一个shell脚本,用于搜集其执行主机的信息,打印结果如下: 
[root@localhost ~]# mkdir /opt/test/script
[root@localhost ~]# cd /opt/test/script
[root@localhost script]# vim test.sh
#!/usr/bin/bash
#获取主机基本信息
time=`date +%F-%T`
#ifconfig命令需要安装net-tools工具包
#ip=`ifconfig |grep broadcast|awk '{print $2}'`    
ip=`hostname -I`
echo "现在的时间是:" $time
echo "当前的用户是:" $USER
echo "当前的用户标识:" $UID
echo "当前的主机名称是:" $HOSTNAME
echo "当前可用网卡IP是:" $ip

[root@localhost script]# source/test.sh 
现在的时间是: 2020-08-22-17:34:03
当前的用户是: root
当前的用户标识: 0
当前的主机名称是: localhost.localdomain
当前可用网卡IP是: 192.168.221.136

//获取当前系统根分区剩余空间
[root@localhost script]# echo "现在系统根分区的剩余空间是":`df -Th | awk 'NR==6 {print $5}'`
现在系统根分区的剩余空间是:48G

//取当前系统剩余内存:
[root@localhost ~]#  echo "现在的剩余内存是:"`free -h |awk 'NR==2 {print $4}'`
现在的剩余内存是:3.4G

//取当前cpu平均负载:
//方式一:
[root@localhost script]# echo "现在cpu的"`uptime | cut -d, -f3-` 
//-d指定分隔符,-f指定显示区域,3-第三列以后(包括第三列)
现在cpu的 load average: 0.00, 0.01, 0.05
#                      1分钟 5分钟  15分钟
#5分钟、15分钟的数值接近CPU的数量的时候就比较危险了

//方式二:
[root@localhost ~]# echo 现在cpu的`uptime | awk -F, '{print $3,$4,$5}'`
    //,作为分隔符,引不引都可以
现在cpu的 load average: 0.00 0.01 0.04

//单独取三个平均负载的值
[root@localhost ~]# uptime |awk -F ":" '{print $5}'
 0.00, 0.01, 0.01

练习2

//编写一个脚本实现收集主机的基本信息,最后脚本还会将这些信息写入一个日志文件
[root@localhost script]# vim xinxi.sh
#!/bin/bash
#获取主机基本信息
centime=`date '+%Y-%m-%d %H:%M:%S'`
nowtime=`uptime |awk '{print $1}'`
username=$USER
average=`uptime |awk -F',' '{print $3,$4,$5}'`
myname=liangzai
cat >>file1.txt <<EOF
echo "时间:$centime"
echo "系统的当前时间是: $nowtime"
echo "系统当前负载: $average"
echo "当前的用户是: $username"
echo "我的名字是: $myname"
EOF
[root@localhost script]# chmod +x xinxi.sh 
[root@localhost script]# ./xinxi.sh 
[root@localhost script]# cat file1.txt
echo "时间:2021-05-07 16:14:41"
echo "系统的当前时间是: 16:14:41"
echo "系统当前负载:   load average: 0.00  0.01  0.04"
echo "当前的用户是: root"
echo "我的名字是: liangzai"

2.变量运算

2.1.基础运算

算式运算符: +、-、*、/、()、%取余(取模)
运算方式:$(()) $[] expr

1.$(())
[root@localhost ~]# echo $(( 5+2-(3*2)/5 )) 
6
[root@localhost ~]# echo $(((3*2)/5))    //除(取整)
1
[root@localhost ~]# echo $(((3*2)%5))    //取余
1

2.$[]
[root@localhost ~]# echo $[ 5 + 2 - (3*2)/5 ]
6 

3.expr
[root@localhost ~]# expr 5 + 3
8
注意:运算符号两边的空格必须写

//乘法运算:
[root@localhost script]# expr 5 \* 3
15
[root@localhost script]# expr 5 '*' 3
15

//脚本案例:
[root@localhost ~]# vim test1.sh
#!/usr/bin/bash
a=2
b=13
echo "$a和$b的和是: $[ $a + $b ]"    #[]也可以用(( ))来替换
echo "$a乘$b的值是: $[ $a * $b ]"
echo "$a和$b的差是: $[ $a - $b ]"
echo "$a和$b的商是: $[ $b / $a ]"
echo "$a和$b的余是: $[ $b % $a ]"
//脚本中常用的方式
echo "$a和$b的和是: `expr $a '+' $b`"

2.2.浮点运算

//bash本身不能做小数计算:需要bc命令转换 
[root@localhost ~]# yum install -y bc
[root@localhost ~]# echo '2.4 * 3'|bc
7.2
[root@localhost ~]# echo '2.2^4'|bc    //次方计算也是可以的
23.4

2.3.随机数

16之间的随机数:
[root@localhost script]# echo $RANDOM    //RANDOM的范围是1-32767
[root@localhost script]# echo $(($RANDOM % 6 + 1))    //取随机数后除以6再取余+1
51-10之间的随机数:
[root@localhost script]# echo $(($RANDOM % 10 + 1))
101~50之间随机数
[root@localhost script]# vim sjs.sh
#!/bin/bash
echo $(($RANDOM % 50 + 1 )) 

//这串代码特别简单,就是利用RANDOM这个随机数生成器进行取余就能够实现

3.变量引用

3.1.转义

转义:\ 反斜杠
当一个字符被引用时,其特殊含义被禁止,把有意义的变的没意义,把没意义的变的有意义
完全引用:’ ’ 强引 硬引
指的是被引号包围起来的变量名【不会进行解析】,原样变量名原样输出,这种方式比较适合定义显示纯字符串的情况,不希望解析变量、命令等的场景。
部分引用: " " 弱引 软引
指的是被引号包围起来的变量名会【先进行解析】,然后将变量的解析结果输出来。这种方式适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。

//转义案例:
[root@localhost ~]# echo you now $1250
you now 250
[root@localhost ~]# echo you now $1250
you now $1250

//例子:
[root@localhost ~]# num=2
[root@localhost ~]# echo 2302班有$num个女生
2302班有2个女生
[root@localhost ~]# echo "2302班有$num个女生"
2302班有2个女生
[root@localhost ~]# echo '2302班有$num个女生'
2302班有$num个女生

//脚本例子
[root@localhost ~]# vim a.sh
#!/usr/bin/bash
echo 'echo $USER' >> b.txt
echo "echo $USER" >> b.txt

3.2.读取用户标准输入read

read:功能就是读取键盘输入的值,并赋给变量
read -t 5 var:-t是时间,5秒内用户必须要输入值
read -p "提示信息" var
read后面的变量var可以只有一个,也可以有多个,这时如果输入多个数据,则第一个数据给第一个变量,第二个数据给第二个变量,如果输入数据个数过多,则最后所有的值都给最后一个变量

[root@localhost ~]# vim test.sh
#!/usr/bin/bash
read -t 10  -p  "请输入你的用户名和密码还有你的年龄: " name pass age
echo "你的名字是 $name"
echo "你的密码是 $pass"
echo "你的年龄是 $age"
#或者也可以将三行echo都写到一句中
#echo "你的名字是 $name","你的密码是 $pass","你的年龄是 $age"
[root@localhost ~]# sh test.sh
请输入你的用户名和密码还有你的年龄: laowang laowang 30
你的名字是 laowang
你的密码是 laowang
你的年龄是 30

#案例1[root@localhost script]# vim readtest.sh
#!/bin/bash
read test
read -p "请输入你的银行卡帐号" num
read -t 5 -p "请在五秒内输入密码" pass
echo "你的密码错误!"
[root@localhost script]# ./readtest.sh
请输入银行卡账号130556652
请输入银行卡密码123456
echo "你的密码错误!"

#案例2:
#自定义程序结果的正确或错误
[root@localhost script]# vim readtest2.sh
#!/bin/bash
read -p "Do you want to continue [Y/N]? " w
case $w in
Y|y)
echo "ok,configure success!";;
N|n)
echo "ok,good bye";;
*)
echo "error choice";;
esac
exit 0
[root@localhost script]# chmod +x readtest2.sh
[root@localhost script]# ./readtest2.sh

#案例3:  #-s 选项 能够使read命令中输入的数据不显示在监视器上
[root@localhost script]# vim readtest3.sh
#!/bin/bash
read -s -p "Enter your password: " pass
echo "your password is $pass"
exit 1
[root@localhost script]# chmod +x readtest3.sh
3localhost script]# ./lianxi.sh
#取消屏幕回显(慎用)
[root@localhost script]# stty -echo #回车测试
[root@localhost script]# stty echo  #恢复回显

#显示变量长度
[root@localhost script]# a=123
[root@localhost script]# echo ${#a}   #表示$var的长度
3

#练习:
[root@localhost script]# cat lianxi.sh
echo 1、将现有的yum源换成阿里云/腾讯云yum源
echo 2、将防火墙和selinux关闭
echo 3、一键安装apache/nginx
echo 4、一键配置静态IP
read -p "请选择你想使用的功能(1/2/3/4):" num
con_ip(){
echo 这是配置IP地址的小工具
}
case $num in
        1):
        ;;
        2):
        ;;
        3):
        ;;
        4)con_ip
        ;;
        *)
        echo "你输入的不正确!请按提示输入"
        ;;
esac
[root@localhost script]# chmod +x lianxi.sh 
[root@localhost script]# ./lianxi.sh

3.3.花里胡哨的echo

  1. 用echo命令打印带有色彩的文字:
    echo -e "\e[1;31m开始解压并安装prometheus\e[0m"
    echo -e "\e[1;31mThis is red text\e[0m"
    This is red text\e[1;31m 将颜色设置为红色
  2. \e[0m 将颜色重新置回
    颜色码:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37
  3. 增加背景色:
    echo -e "\e[1;42mGreed Background\e[0m"
    Greed Background颜色码:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47
  4. 文字闪动:
    echo -e "\033[37;31;5mMySQL Server Stop...\033[39;49;0m"
    红色数字处还有其他数字参数:0 关闭所有属性、1 设置高亮度(加粗)、4 下划线、5 闪烁、7 反显、8 消隐

4.变量置换

4.1.命令替换

//取命令的结果用的,把执行的命令结果拿出来
[root@localhost ~]# a=`date +%m%d`
[root@localhost ~]# echo $a
1225
[root@localhost ~]# a=$(date +%m-%d)
[root@localhost ~]# echo $a
12-25//反引号亦可用$() 代替

4.2.变量替换

${parameter:-word}        parameter:参数
${a:-3}
若 parameter 为空或未设置,则用 word 代替 parameter 进行替换,parameter 的值不变;若 parameter 不为空,则不替换,parameter 的值不变

[root@localhost ~]# a=123
[root@localhost ~]# echo $a
123
[root@localhost ~]# unset a
[root@localhost ~]# echo $a
​
[root@localhost ~]# echo ${a:-3}
3
[root@localhost ~]# echo ${a}   //再次打印$a,发现还是空值,说明${a:-3}只是临时赋值

//有值时,不会发生改变
[root@localhost ~]# a=123
[root@localhost ~]# echo $a
123
[root@localhost ~]# echo ${a:-3}
123

${parameter:=word}
若 parameter 为空或未设置,则用 word 代替 parameter 进行替换,parameter 的值改变;若 parameter设置了,则不替换,parameter的值不变

[root@localhost ~]# a=123
[root@localhost ~]# echo $a
123
[root@localhost ~]# echo ${a:=3}
123
[root@localhost ~]# a=
[root@localhost ~]# echo $a
​
[root@localhost ~]# echo ${a:=3}
3
[root@localhost ~]# echo $a
3

它俩(${parameter:-word}和${parameter:=word})的区别:
parameter有值时,它俩都不会将现有的值覆盖掉,所以区别是体现在parameter为空时,-word是将赋的值临时生效,=word会将赋的值永久生效

${parameter:+word}
若parameter 设置了值时,则用 word 代替 parameter 进行临时替换,parameter 的值不变;用的较少

[root@localhost ~]# b=1
[root@localhost ~]# echo ${b:+3}
3
[root@localhost ~]# unset b
[root@localhost ~]# echo $b     //为空时,不会输出任何值[root@localhost ~]# echo ${b:+3}

​案例:安装mysql脚本

[root@localhost ~]# vim mysql.sh
#!/usr/bin/bash
read -p "请选择你要安装的mysql版本,默认为5.7:" var
echo "默认的mysql版本为${var:-5.7}"
echo "你选择的版本是$var"

4.3.变量替换——匹配截取

1.索引及切片

[root@localhost ~]# a=12345678
[root@localhost ~]# echo ${a:5}    //从左往右第5位开始截取,留下后面的所有 
678
[root@localhost ~]# echo ${a:3:4}    //从第3位开始截取,留下后四位的,剩下的都不要。
4567
[root@localhost ~]# echo ${a:2:-1}    //从左往右第2位开始截取,从右往左截取第一位
34567
[root@localhost ~]# echo ${a:2:-2}
3456
[root@localhost ~]# echo ${a::-5}
123
​
​脚本案例:
[root@localhost ~]# vim test11.sh
#!/usr/bin/bash
read -s -p "请输入您的手机号  " phone 13500001111
echo "你的手机号是 $phone"
echo "手机号后四位是 ${phone:7}"
#或:
echo "您的手机号后四位是${phone:7:4}"    //从第7位开始截取,留下后四位,剩下的都不要。

2.变量截取 【最短】=【最近】、【最长】=【最远】

${变量#关键词} 若变量内容【从头开始/从左到右】的数据符合【关键词】,则将符合的【最短】数据切除
${变量##关键词} 若变量内容【从头开始/从左到右】的数据符合【关键词】,则将符合的【最长】数据切除
${变量%关键词} 若变量内容【从尾向前/从右向左】的数据符合【关键词】,则将符合的【最短】数据切除
${变量%%关键词} 若变量内容【从尾向前/从右向左】的数据符合【关键词】,则将符合的【最长】数据切除

练习1:
[root@localhost ~]# url=www.sina.com.cn 
[root@localhost ~]# echo ${#url}    //获取变量的长度 
15
[root@localhost ~]# echo ${url}    //正常显示变量 
www.sina.com.cn
​
变量内容的删除
[root@localhost ~]# echo ${url#*.}   从前往后匹配到“.”最短匹配(将最短的截取掉,剩下的展示)
sina.com.cn
[root@localhost ~]# echo ${url##*.}  从前往后匹配到“.”,最长匹配(将最长的截取掉,剩下的展示出来)
cn
[root@localhost ~]# echo ${url%.*}   从后往前匹配到“.”,最短匹配
www.sina.com
[root@localhost ~]# echo ${url%%.*}  从后往前匹配到“.”,最长匹配
www
​
练习2:
[root@localhost ~]# url=https://test.com.cn/abc/index.html
从前往后匹配
[root@localhost ~]# echo ${url#*/}
/test.com.cn/abc/index.html
[root@localhost ~]# echo ${url##*/}
index.html
​
从后往前匹配,注意*号的顺序!
[root@localhost ~]# echo ${url%/*}
https://test.com.cn/abc
[root@localhost ~]# echo ${url%%/*}
https:
​
练习3:
file=/dir1/dir2/dir3/my.file.txt
${file#*/}:  拿掉第一条  / 及其左边的字符串:dir1/dir2/dir3/my.file.txt 
${file##*/}: 拿掉最后一条 / 及其左边的字符串:my.file.txt 
${file#*.}:  拿掉第一个 . 及其左边的字符串:file.txt
${file##*.}: 拿掉最后一个 . 及其左边的字符串:txt
${file%/*}:  拿掉最后一条 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}: 拿掉第一条 / 及其右边的字符串:(空值)
${file%.*}:  拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}: 拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
​
#脚本案例:
[root@localhost ~]# vim mail.sh
#!/usr/bin/bash
read -p "请输入你的邮箱 " mail
echo "你的邮箱是$mail"
echo "你的邮箱服务器是${mail#*@}"   #从前往后匹配到“@”最短匹配
#例:
[root@localhost ~]# [email protected]
[root@localhost ~]# echo ${mail#*@}
163.com
​
#完整脚本
#!/usr/bin/bash
read -p "请输入你的邮箱 " mail
echo "你的邮箱是$mail"
echo "你的邮箱服务器是${mail#*@}"   #从前往后匹配到“@”最短匹配
mail_host=${mail#*@}
case $mail_host in
        163.com)
        echo "网易邮箱服务器"
        ;;
        126.com)
        echo "126服务器"
        ;;
        qq.com)
        echo "qq邮箱"
        ;;
        *)
        echo "您输入的邮箱不正确"
        exit 2
esac

​参数解释:
*: 表示全部字符。
%: 最短末尾匹配;
%%:最大末尾匹配
%: 从右往左
#: 从左往右
用冒号截取:echo $a: : :

3.变量内容的替换

${变量/旧字符串/新字符串} 若变量内容符合【旧字符串】则【第一个旧字符串会被新字符串替代】
${变量//旧字符串/新字符串} 若变量内容符合【旧字符串】则【全部的旧字符串会被新字符串替代】

[root@localhost ~]# a=123456123789
[root@localhost ~]# echo ${a/1/}    //第一次匹配的被替换
23456123789
[root@localhost ~]# echo ${a/1/0}    //第一次匹配到1替换成0
023456123789
[root@localhost ~]# echo ${a//1/}    //全局的匹配被替换
2345623789                 
[root@localhost ~]# echo ${a//1/x}    //全局匹配到1替换成x
x23456x23789

4.4.basename && dirname

#basename 命令
#basename 是去除目录后剩下的名字,取文件名或目录名
//例: 
[root@localhost ~]# file=/tmp/test/test1.txt
[root@localhost ~]# echo $file
/tmp/test/test1.txt
[root@localhost ~]# basename $file
test1.txt
​
#dirname 是取目录名 
//例:
[root@localhost ~]# file=/tmp/test/test1.txt
[root@localhost ~]# echo $file
/tmp/test/test1.txt
[root@localhost ~]# dirname $file
/tmp/test

你可能感兴趣的:(Shell,linux,centos,bash)