shell脚本编程之测试和条件语句if;case;echo;正则表达式;位置锚定

96 阅读3分钟

一.条件语句

1.条件语句测试

test 测试文件的表达式 是否成立

格式1:test 条件表达式 格式2:[ 注意两边需要空格 ] 格式3:[操作符 文件或者目录]


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

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

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

test

image.png

[ ]

image.png

2.比较整数数值

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

  • eq:第一个数等于(Equal)第二个数
  • -ne:第一个数不等于(Not Equal)第二个数
  • -gt:第一个数大于(Greater Than)第二个数
  • -lt:第一个数小于(Lesser Than)第二个数
  • -le:第一个数小于或等于(Lesser or Equal)第二个数
  • -ge:第一个数大于或等于(Greater or Equal)第二个数

示例

image.png

image.png

3.字符串比较

常用的测试操作符

  • =:字符串内容相同
  • !=:字符串内容不同,! 号表示相反的意思
  • -z:字符串内容为空
  • -n: 字符是否存在

格式

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

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

[ -z 字符串 ] 是否为空

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

image.png

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

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

常见条件

  • -a或&&:逻辑与,“而且”的意思全真才为真
  • -o或||:逻辑或,“或者”的意思一真即为真
  • !:逻辑否

1)短路与 &&:全真才为真 一假即为假

  1. CMD1 短路与 CMD2 && 同时满足命令1 和命令2 的要求 才会返回正确
  2. 全真才为真 一假即为假
  3. 第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果
  4. 第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2

image.png

2)短路或 ||:一真即为真

  1. CMD1 短路或 CMD2
  2. 一真即为真
  3. 第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2
  4. 第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果

image.png

示例1.

image.png

示例2:

ping -c 3 -i 0.5 -W2 1 &> /dev/null && echo "1 online" || echo "$1 off"

image.png

image.png

5. 双中括号 [[ expression ]]

[[ expression ]] 用法

  • == 左侧字符串是否和右侧的PATTERN相同

注意:此表达式用于[[ ]]中,PATTERN为通配符

  • =~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配

注意: 此表达式用于[[ ]]中;扩展的正则表达式

示例:

#通配符

[root@centos8 ~]#FILE=test.log
[root@centos8 ~]#[[ "$FILE" == *.log ]]   判断是否匹配
[root@centos8 ~]#echo $?
0
[root@centos8 ~]#FILE=test.txt
[root@centos8 ~]#[[ "$FILE" == *.log ]]
[root@centos8 ~]#echo $?
1
[root@centos8 ~]#[[ "$FILE" != *.log ]]
[root@centos8 ~]#echo $?
0

6. () {}

格式:

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

将命令结合在一起

image.png

二. 条件语句

1.if语句的结构

  if     判段条件
  then   条件为真的分支代码
  elif   判断条件2
  else   条件为假的分支代码
  fi     结尾

单分支

if 判断条件;

then 条件为真的分支代码

fi

双分支

if 判断条件;

then 条件为真的分支代码

else 条件为假的分支代码

fi

多分支

if 判断条件1

then 条件1为真的分支代码

elif 判断条件2

then 条件2为真的分支代码

elif 判断条件3;

then 条件3为真的分支代码

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

fi

1)

image.png


2) image.png


3) image.png


image.png

2. case

格式

case  变量应用 in
模式1)
     命令分支1
     ;;
 模式2)
      命令分支2
      ;;
   ...
   *)
    默认命令分支
  esac  

注意事项

  • case支持glob风格的通配符:
    • 任意长度任意字符
  • ? 任意单个字符
  • [0-9] 指定范围内的任意单个字符
  • |   或者,如: a|b

image.png


3. echo

  • echo -n 表示不换行输出

  • echo -e 表示输出转义符

常用的转义符

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

示例:

image.png

前引:

通配符与正则表达式的区别?

1 通配符一般用户文件名匹配

2 正则表达式一般用于匹配文件内容

正则表达式 过滤文本

由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通配符不同,通配符功能是用来处理文件名,而正则表达式是处理文本内容中字符。

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

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

  • 基本正则表达式
  • 扩展正则表达式

可以使用 man 7 regex手册帮助

元字符(字符匹配)

  1. .   匹配任意单个字符,可以是一个汉字
  2. []   匹配指定范围内的任意单个字符,示例:[zhou]   [0-9]   []   [a-zA-Z]
  3. [^] 匹配指定范围外的任意单个字符,示例:[^zhou] [^a.z] [a.z]

元字符点(.)

image.png

image.png

元字符点[ ]

 [root@localhost ~]# ls |grep '[zhou].txt' 
 [root@localhost ~]# ls [a-d].txt  
 ls |grep '[a-d].txt'  

元字符点[^ ]

 ls |grep '[^a-z].txt'     :显示非小写字母
 ls |grep '[^a.z].txt'    []里就是本意不需要转义
匹配符2功能
[:alnum:]字母和数字
[:alpha:]代表任何英文大小写字符,亦即 A-Z, a-z
[:upper:]大写字母,相当于[A-Z]
[:lower:]小写字母,相当于[a-z]
[:blank:]空白字符(空格和制表符)
[:space:]包括空格、制表符(水平和垂直)、换行符、回车符等各种类型的空白
[:cntrl:]不可打印的控制字符(退格、删除、警铃…)
[:digit:]十进制数字
[:xdigit:]十六进制数字
[:print:]可打印字符
[:graph:]可打印的非空白字符
[:punct:]标点符号

表示次数

 1. * 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
 2. .* 任意长度的任意字符,不包括0次
3. \? 匹配其前面的字符出现0次或1次,即:可有可无
4. \+ 匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
5. \{n\} 匹配前面的字符n次
6. \{m,n\} 匹配前面的字符至少m次,至多n次
7. \{,n\}  匹配前面的字符至多n次,<=n
8. \{n,\} 匹配前面的字符至少n次
9. ifconfig ens33|grep netmask|grep -o 

image.png


image.png


image.png


image.png

位置锚定

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

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

示例:

image.png

 grep "^google$" test.txt   #只匹配google 这个字符
 grep "^[[:space:]]*$" /etc/fstab
 echo hello-123 |grep "\<123" #除了 字母 数字 下划线其他都算 单词的分隔符

分组或其他

分组:() 将多个字符捆绑在一起,当作一个整体处理,如:(root)+

后向引用:分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名

方式为: \1, \2, \3, ...

\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

或者

或者

或者:\ |

image.png

image.png

image.png

image.png

image.png

扩展正则表达式

grep -E

egrep

表示次数

字符含义
*匹配前面字符任意次
?0或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

1表示qq号

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

2.表示邮箱3.表示手机号

echo "zhou@qq.com" |grep -E "[[:alnum:]_]+@[[:alnum:]_]+\.[[:alnum:]_]+"

3.表示手机号

echo "13705173391"|grep -E "\b1[3456789][0-9]{9}\b"