Linux系统中Shell脚本之条件语句、循环语句及正则表达式

目录

一.条件语句

1.条件测试

2.比较整数数值

3.字符串比较

4.逻辑测试(短路运算)

5.双中括号

6.() {}

7.if语句的结构

7.1分支结构

8.case

9.echo

二.循环语句​

1.循环含义

2.for 语法结构

2.1列表循环

2.2不带列表循环

2.3 类似于C语言风格的for循环

3.while  

 4.双重循环及跳出循环

5.until

三.正则表达式

1. 元字符(字符匹配)

2.表示次数 

3.位置锚定

4.扩展正则表达式(表示字符相差不大)

5.grep


一.条件语句

1.条件测试

格式1:test  条件表达式
格式2:[  条件表达式  ]
注意[]空格,否则会失败
测试 是否成功使用 $?  返回值
[ 操作符 文件或目录 ]
help test

操作符:
-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-a:测试目录或文件是否存在(Exist)   
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)
-L: 测试是否为软连接文件

属性测试补充:
-s FILE #是否存在且非空
-t fd #fd 文件描述符是否在某终端已经打开
-N FILE #文件自从上一次被读取之后是否被修改过
-O FILE #当前有效用户是否为文件属主
-G FILE #当前有效用户是否为文件属组

条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成

测试过程,实现评估布尔声明,以便用在条件性环境下进行执行

若真,则状态码变量 $? 返回0

若假,则状态码变量 $? 返回1

条件测试命令

例子:

[root@test1 ~]# test -d /etc/sysconfig
[root@test1 ~]# echo $?
0
[root@test1 ~]# test -f /etc/sysconfig
[root@test1 ~]# echo $?
1
[root@test1 ~]# [ -d /etc/sysconfig/ ]            注意前后空格
[root@test1 ~]# echo $?
0
[root@test1 ~]# [ -f /etc/sysconfig/ ]
[root@test1 ~]# echo $?
1

2.比较整数数值

[ 整数1 -操作符 整数2 ] 公式

  • -eq:第一个数等于(Equal)第二个数

  • -ne:第一个数不等于(Not Equal)第二个数

  • -gt:第一个数大于(Greater Than)第二个数

  • -lt:第一个数小于(Lesser Than)第二个数

  • -le:第一个数小于或等于(Lesser or Equal)第二个数

  • -ge:第一个数大于或等于(Greater or Equal)第二个数

例子:

[  整数1  操作符  整数2  ]
[root@test1 ~]# a=2        
[root@test1 ~]# b=3
[root@test1 ~] [ $a -eq $b ]
[root@test1 ~]# echo $?
1
[root@test1 ~]# [ 2 -le 3 ]
[root@test1 ~]# echo $?
0

3.字符串比较

常用的测试操作符

•  =:字符串内容相同  

•  !=:字符串内容不同,! 号表示相反的意思  

•  -z:字符串内容为空  

•  -n: 字符是否存在  

格式

[  字符串1 =  字符串2 ]  是否相同

[  字符串1  !=  字符串2 ]  是否不相同

[  -z  字符串 ]   是否为空

[  -n  字符串 ] 字符是否存在

4.逻辑测试(短路运算)

格式1:[  表达式1  ]  操作符  [  表达式2  ]  ... 
格式2:命令1  操作符  命令2  ...  ​ ​ ​

第一个要真   第二 个也要真     才能是真 如果第一个为假 ,整个 就为假 不用执行下个操作

cmd1  && cmd2 ​

一 真即为真 如果第一个 为真 那么   不用执行第二个 第一个为假 ,才需要执行第二个

cmd1 || cmd2

常见条件

•  -a或&&:逻辑与,“而且”的意思全真才为真  

•  -o或||:逻辑或,“或者”的意思一真即为真  

•  !:逻辑否  

5.双中括号

[[ expression ]] 用法
== 左侧字符串是否和右侧的PATTERN相同
注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
注意: 此表达式用于[[  ]]中;扩展的正则表达式

6.() {}

(CMD1;CMD2;...)和 {    CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行 ​

7.if语句的结构

7.1分支结构

单分支

if 判断条件;

then   条件为真的分支代码

fi

双分支


if 判断条件

 then
 条件为真的分支代码

else
 条件为假的分支代码

fi

多分支

if 判断条件1
then
 条件1为真的分支代码

elif 判断条件2
then
 条件2为真的分支代码

elif 判断条件3;then
 条件3为真的分支代码

...
else
 以上条件都为假的分支代码  托底

fi

8.case

格式:

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac

read -p          i

case $i in
PAT1)
 分支1
 ;;
PAT2)
 分支2
 ;;
...
*)
 默认分支
 ;;

esac

case支持glob风格的通配符:

* 任意长度任意字符

? 任意单个字符

[0-9] 指定范围内的任意单个字符

|  或者,如: a|b

9.echo

echo -n   表示不换行输出
echo -e   表示输出转义符
#常用的转义符

二.循环语句​

选项作用
\r光标移至行首,并且不换行
\s当前shell的名称,如bash
\t插入Tab键,制表符
\n输出换行
\f换行,但光标仍停留在原处
\表示插入"\"本身转义
\b表示退格 不显示前一个字符
\c抑制更多的输出或不换行

date

date查看当前系统时间

-d  你描述的日期,显示指定字符串所描述的时间,而非当前时间  

%F 完整日期格式,等价于 %Y-%m-%d

%T 时间(24小时制)(hh:mm:ss)

1.循环含义

将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件

重复运行次数

  • 循环次数事先已知 for 已知次数情况下

  • 循环次数事先未知 while 和 until 是已知条件

常见的循环的命令:for, while, until

2.for 语法结构

•  列表循环  

•  不带列表循环  

•  类C风格的for循环   ​

2.1列表循环

语法:

for 变量名 in   {list}
do
   command
done

花括号的用法

花括号{}和seq在for循环的应用:
for i in {1..50..2} 1-50的奇数

for i in {2..50..2} 1-50的偶数
for i in {10..1}  1-10倒序排列

for i in $(seq 10)  1-10正序排列
for i in $(seq 10 -1 1) 1-10倒序排列
for i in $(seq 1 2 10) 1-10的奇数,中间为步长

2.2不带列表循环

语法:

for 变量名
do
   command
done

例子:

例1:打印hello
第一种:
[root@server ~]# vim for2.sh

#!/bin/bash
for i    
do
       echo hello
done

[root@server ~]# . for2.sh  
#没有给脚本传参所以执行了没有结果

[root@server ~]# . for2.sh a  
#把a赋值给变量i,i有值了它就开始执行do..done了
hello

2.3 类似于C语言风格的for循环

语法:

for ((expr1;expr2;expr3))
do
      command
done

expr1:定义变量并赋初值
expr2:决定是否循环
expr3:决定循环变量如何改变,决定循环什么时候退出

sum=1   i2=2
sum+=i    等于   sum=sum+i  


#需要使用 let  命令

++  自身变量+1  
--  自身变量-1    
+=5 自身变量+5  
-=5 自身变量-5
*=5 自身变量*5
/=5 自身变量/5
%=5 自身变量%5

3.while  

相对于for,需要知道循环次数,如果我们只知道停止条件,不知道次数,就需要使用while 直到达到条件  

while循环
1、语法结构

while  :
do


done

while
当命令判断为假时停止

2、死循环 while循环一般用于有条件判断的循环,若判断条件为真,则进入循环,当条件为假就跳出循环 ​

while死循环
while [ 1 -eq 1 ]  //写一个永远为真的表达式,1等于1这个条件永远为真,所以这个脚本会一直循环下去
do
    command
done


while true
do
    command
done
 

 4.双重循环及跳出循环

•  break跳出单个循环 break n  数字数字是几代表跳出n层循环  

•  continue终止某次循环中的命令,但是不会完全终止命令  

•  exit  直接退出脚本

5.until

until 循环与 while 循环类似,while 循环能实现的脚本 until 同样也可以实现,但区别是while 循环在条件为真是继续执行循环,而 until 则是在条件为假时执行循环

until 循环语句的语法结构如下所示。

until 条件测试操作
do
命令序列
done

实例:求和          ​

#!/bin/bash

sum=0

i=0

until [ $i -gt 100 ]

do

let sum=$i+$sum

let i++

done

echo sum=$sum​     

菜单脚本

#!/bin/bash
sum=0
PS3="请输入(1-6):"
MENU="
宫保鸡丁
酸菜鱼
鱼香肉丝
佛跳墙
水煮肉片
点菜结束
"

select menu in $MENU
do
case $REPLY in
1)
echo $menu 价格是20
let sum+=20
;;
2)
echo $menu 价格是60
let sum+=60
;;


3)
echo $menu 价格是25
let sum+=25
;;

4)
echo $menu 价格是150
let sum+=150
;;

5)
echo $menu 价格是60
let sum+=60
;;

6)
echo "点菜结束"
break
;;

*)
echo "点菜错误,请重新选择"
;;

esac
done

echo "总价是$sum"

三.正则表达式

主要用来匹配字符串(命令结果,文本内容)

通配符匹配文件(而且是已存在的文件)

  • 基本正则表达式

  • 扩展正则表达式

可以使用

man 7 regex
可以使用 man手册帮助

1. 元字符(字符匹配)

元字符:

注册用户 数字字母组成 20字符

[0-9a-zA-Z]次数

单个字符出现的次数

echo ”用户名“ | grep [0-9a-zA-Z]次数 (20个及以下)

.   匹配任意单个字符,可以是一个汉字  
[]   匹配指定范围内的任意单个字符,示例:[zhou]   [0-9]   []   [a-zA-Z]   [[:alpha:]]    [0-9a-zA-Z]= [:alnum:]
[^] 匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] [a.z]
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 包括空格、制表符 (水平和垂直)、换行符、回车符等各种类型的空白,比[:blank:]包含的范围广
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
\w #匹配单词构成部分,等价于[_[:alnum:]]
\W #匹配非单词构成部分,等价于[^_[:alnum:]]
\S     #匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\s     #匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意Unicode 正则表达式会匹配全角空格符

2.表示次数 

* #匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
.* #任意长度的任意字符  不包括0次    
\? #匹配其前面的字符出现0次或1次,即:可有可无
\+ #匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
\{n\} #匹配前面的字符n次
\{m,n\} #匹配前面的字符至少m次,至多n次
\{,n\}  #匹配前面的字符至多n次,<=n
\{n,\}  #匹配前面的字符至少n次

3.位置锚定

^ #行首锚定, 用于模式的最左侧
$ #行尾锚定,用于模式的最右侧
^PATTERN$ #用于模式匹配整行 (单独一行  只有root)
^$ #空行  
^[[:space:]]*$ #  空白行    tab   换行  回车

\< 或 \b        #词首锚定,用于单词模式的左侧(连续的数字,字母,下划线都算单词内部)
\> 或 \b        #词尾锚定,用于单词模式的右侧
\<PATTERN\>     #匹配整个单词

4.扩展正则表达式(表示字符相差不大)

grep -E

egrep 默认使用的 是扩展正则表达式

表示次数

*   匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
{,n}  #匹配前面的字符至多n次,<=n,n可以为0
{n,} #匹配前面的字符至少n次,<=n,n可以为0

表示分组

() 分组
分组:() 将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+
后向引用:\1, \2, ...
| 或者  
a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat

例子:表示qq号

[root@localhost ~]#echo "aa940132245" |grep "\b[0-9]\{6,12\}\b"

5.grep

格式:grep [选项]… 查找条件 目标文件

选项:
-color=auto #对匹配到的文本着色显示
-m  # 匹配#次后停止      匹配到 #行停止
grep -m 1 root /etc/passwd   #多个匹配只取第一个
-v 显示不被pattern匹配到的行,即取反
grep -Ev '^[[:space:]]*#|^$' /etc/fstab
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
grep -c root /etc/passwd    #统计匹配到的行数
-o 仅显示匹配到的字符串
-q 静默模式,不输出任何信息   写脚本
-A # after, 后#行 
grep -A3 root /etc/passwd   #匹配到的行后3行业显示出来
-B # before, 前#行
-C # context, 前后各#行
-e 实现多个选项间的逻辑or关系,如:grep –e ‘cat ' -e ‘dog' file
grep -e root -e bash /etc/passwd #包含root或者包含bash 的行
grep -E root|bash  /etc/passwd
-w 匹配整个单词
grep -w root /etc/passwd
useradd rooter
-E 使用ERE,相当于egrep
-F 不支持正则表达式,相当于fgrep
-f   file 根据模式文件,处理两个文件相同内容 把第一个文件作为匹配条件   grep  -f a   b
-r   递归目录,但不处理软链接     开始搜索目录
-R   递归目录,但处理软链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值