在正则表达式中,使用匹配的特殊符号又称作是元字符
元字符又分为基础元字符和扩展元字符;
基础元字符
*: 匹配前一个字符0次或者N次
.: 匹配换行符{\n 空格\t}以外的任意一个字符
^: 匹配行首;例如,匹配^hello会匹配以hello开头的行
$: 匹配行尾,例如,匹配hello$
^$: 匹配空行
[]: 匹配中括号中指定的任意一个字符
[^]: 匹配中括号中非指定的字符
\: 转义字符,取消特殊字符的含义
\{n\}: 表示前面的一个字符刚好出现n次,匹配手机号码-->[1][3-8][0-9]\{9\}
\{n,\}: 表示前面一个字符出现不少于n次,例如[0-9]\{2,\}-->表示匹配两个以上的数字
\{n,m\}: 表示前面的字符至少出现n次,最多出现m次
实验讲解
元字符的使用我们是使用grep命令来验证
grep命令支持正则表达式;grep -E相当于egrep可以支持扩展中的正则
grep命令是支持普通元字符的,使用扩展功能就需要结合选项-E
grep -F 或者是fgrep基本上是不用
#做好前提准备;准备grep出来的信息有红色显示,修改一下别名/root/.bashrc
[root@server ~]# vim .bashrc
...........
alias grep='grep --color=auto' #添加这一行;
#建立测试文件
[root@server ~]# vim test_rule.txt
Mr. Li Ming said:
he was the most honest man in LampBrother.
123despise him.
But since Mr. shen Chao came,
he never saaaid those words.
5555nice!
because,actuaaaally,
Mr. Shen Chao is the most honest man Later,Mr. Li ming soid his hot body.
*匹配前一个字符匹配0次或者任意多次
[root@server ~]# grep "a*" test_rule.txt
#这里出现了全文;因为匹配前一个字符0次或者任意多次,因此,a可以不出现;也可以出现;
#因此a*这类型的写法是没有任何意义的
#匹配至少一个a的行
[root@server ~]# grep "aa*" test_rule.txt
#匹配连续的aa
[root@server ~]# grep "aaa*" test_rule.txt
he never saaaid those words.
because,actuaaaally,
.表示匹配任意一个字符
#匹配s..d中间任意两个字符
[root@server ~]# grep "s..d" test_rule.txt
Mr. Li Ming said:
Mr. Shen Chao is the most honest man Later,Mr. Li ming soid his hot body.
#匹配s和d中间可以存在任意字符并且是任意个数
[root@server ~]# grep "a.*" test_rule.txt
Mr. Li Ming said:
he was the most honest man in LampBrother.
But since Mr. shen Chao came,
he never saaaid those words.
because,actuaaaally,
Mr. Shen Chao is the most honest man Later,Mr. Li ming soid his hot body.
^匹配行首
#匹配以大写M开头的行
[root@server ~]# grep "^M" test_rule.txt
Mr. Li Ming said:
Mr. Shen Chao is the most honest man Later,Mr. Li ming soid his hot body.
$匹配行尾
[root@server ~]# grep "n$" test_rule.txt
[root@server ~]# grep "y$" test_rule.txt
#这里很明显发现怎么匹配不出来
注意:如果文档是从windows复制过去的,那么n$是不能正确执行的,因为windows中的换行符是“^M$”,因此换行符不同,也不能正确判断行尾字符串
[root@server ~]# dos2unix test_rule.txt
dos2unix: converting file test_rule.txt to Unix format ...
^$匹配空白行
[root@server ~]# grep -n "^$" a.tx
2:
4:
6:
9:
10:
[]中括号讲解,匹配括号中任意一个字符,且仅匹配一个字符
#匹配要么3 要么a的行
[root@server ~]# grep [a,3] a.tx
aaaaabbbb
3333444444
#匹配以数字开头的行
[root@server ~]# grep "^[0-9]" test_rule.txt
123despise him.
5555nice!
#匹配以大写字母开头的行
[root@server ~]# grep "^[A-Z]" test_rule.txt
Mr. Li Ming said:
But since Mr. shen Chao came,
Mr. Shen Chao is the most honest man Later,Mr. Li ming soid his hot body.
\转义字符讲解
#如果AA是个变量
[root@server ~]# echo $AA
1
[root@server ~]# echo \$AA
$AA
\{n\}:匹配前面的字符刚好出现n次
#匹配文档中出现a刚好3次的行
[root@server ~]# grep "a\{3\}" a.tx
aaaaabbbb
#这里能够看到同样的5个a也能匹配出来,但是它是包含三个a的
#匹配连续三个都是字母的行
[root@server ~]# grep "^[0-9]\{3\}[a-z]" test_rule.txt
123despise him.
"\{n,\}"表示其前面的字符出现不少于 n 次
[root@server ~]# grep "[su]a\{3,\}[il]" test_rule.txt
he never saaaid those words.
because,actuaaaally,
\{n,m\}表示其前面的字符出现至少n次,至多m次
[root@server ~]# grep "sa\{1,3\}" test_rule.txt
Mr. Li Ming said:
he never saaaid those words.
扩展元字符
这里需要了解的是,grep是默认不支持这些扩展的元字符的
需要使用到grep -E 或者是egrep命令执行
扩展元字符的解释
+: 表示前面的字符匹配1次或者任意多次
?: 前一个字符匹配0次或者1次
|: 匹配两个或者多个分支选择(逻辑或)
(): 匹配其整体为一个字符,模式单元,
shell是一门编程语言,正如C C++ java php Python Go等类似
Shell语言支持大部分编程语言都具备的功能:if判断,for循环,变量,数组,函数,加减乘除,逻辑运算
语言的分类:
1)编译型语言:C C++ Go等为编译型语言,程序运行需要提前编译,编译语言都有编译器
2)解释型语言:Shell Python php等为解释型语言,程序运行不需要提前编译,一边执行,一边解释,每种解释型语言都有解释器
shell脚本的组成
[root@Node4 sh]# vim first.sh
#!/bin/bash # 声明环境
#2022年5月9日 #日期
#Author By Liangjiawei #作者是谁
#Usage first shell sh #用途是什么
#################################### #华丽的分割线
如何写好一个shell脚本
编写第一个脚本
[root@Node4 sh]# vim hello.sh
#!/bin/bash
#hello word
echo "hello the word"
#赋予执行权限
[root@Node4 sh]# chmod +x hello.sh
[root@Node4 sh]# ll hello.sh
-rwxr-xr-x 1 root root 46 5月 10 14:06 hello.sh
#执行脚本
[root@Node4 sh]# ./hello.sh
hello the word
#编写创建用户的脚本
[root@Node4 sh]# vim useradd.sh
#!/bin/bash
#2022年5月10日
#Author By Linagjiawei
#Usage:useradd user
###############################
useradd abc
echo "1" | passwd --stdin abc
#执行脚本
[root@Node4 sh]# bash useradd.sh
更改用户 abc 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@Node4 sh]# vim info.sh
#!/bin/bash
#2022年5月10日
#Author By liangjiawei
#Usage info
################################
cat /etc/redhat-release
uname -r
free -h
ifconfig ens32
hostname
#赋予执行权限
[root@Node4 sh]# chmod +x useradd.sh
[root@Node4 sh]# ll useradd.sh
-rwxr-xr-x 1 root root 147 5月 10 14:09 useradd.sh
#执行脚本
[root@Node4 sh]# ./info.sh
CentOS Linux release 7.6.1810 (Core)
3.10.0-957.el7.x86_64
total used free shared buff/cache available
Mem: 1.9G 153M 1.6G 9.4M 153M 1.6G
Swap: 2.0G 0B 2.0G
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.75.134 netmask 255.255.255.0 broadcast 192.168.75.255
inet6 fe80::20c:29ff:fe59:c551 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:59:c5:51 txqueuelen 1000 (Ethernet)
RX packets 1933 bytes 164280 (160.4 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1227 bytes 145546 (142.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Node4
#编写搭建本地yum源仓库脚本_V1版本-->丢人版本
[root@Node4 sh]# vim yum_v1.sh
#!/bin/bash
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
echo '/dev/cdrom /mnt/cdrom iso9660 defaults 0 0' >> /etc/fstab
rm -rf /etc/yum.repos.d/*
touch /etc/yum.repos.d/local.repo
echo "[local]" > /etc/yum.repos.d/local.repo
echo "name=local.repo" >> /etc/yum.repos.d/local.repo
echo "baseurl=file:///mnt/cdrom" >> /etc/yum.repos.d/local.repo
echo "enabled=1" >> /etc/yum.repos.d/local.repo
echo "gpgcheck=0" >> /etc/yum.repos.d/local.repo
#编写搭建本地yum源仓库脚本_V2版本-->标准版本
[root@Node4 sh]# vim yum.sh
#!/bin/bash
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
echo '/dev/cdrom /mnt/cdrom iso9660 defaults 0 0' >> /etc/fstab
rm -rf /etc/yum.repos.d/*
touch /etc/yum.repos.d/local.repo
echo '[local]
name=local.repo
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0' > /etc/yum.repos.d/local.repo
#编写搭建本地yum源仓库脚本_V3版本-->升级版
[root@Node4 sh]# vim yum_v3.sh
#!/bin/bash
echo "正在配置本地yum源.................."
mkdir /mnt/cdrom
mount /dev/cdrom /mnt/cdrom &> /dev/null
echo '/dev/cdrom /mnt/cdrom iso9660 defaults 0 0' >> /etc/fstab
rm -rf /etc/yum.repos.d/*
touch /etc/yum.repos.d/local.repo
echo '[local]
name=local.repo
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0' > /etc/yum.repos.d/local.repo
echo "本地yum仓库已经完成......"
yum clean all &> /dev/null
yum repolist all | tail -1
#执行脚本查看
[root@Node4 sh]# bash yum_v3.sh
正在配置本地yum源..................
本地yum仓库已经完成......
repolist: 4,021
#编写搭建本地yum源仓库脚本_V4版本-->高级版本-->带进度条的
[root@Node4 sh]# vim yum_v4.sh
#!/bin/bash
echo "====正在配置本地yum源======"
b=' '
for ((i=0;$i<=20;i++))
do
let jinshu=$i*5
printf "[%-20s]%d%%\r" $b $jinshu
sleep 0.1
b=#$b
done
echo
rm -rf /etc/yum.repos.d/*
echo '[local]
name=local.repo
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0' > /etc/yum.repos.d/local.repo
x=`yum repolist all | tail -1 | awk '{print $2}'`
echo "软件包数量为$x"
#执行查看
[root@Node4 sh]# bash yum_v4.sh
====正在配置本地yum源======
[####################]100%
软件包数量为4,021
#绝对路径执行脚本
[root@Node4 sh]# vim hello.sh
#!/bin/bash
echo hello world
#赋予执行权限
[root@Node4 sh]# chmod +x hello.sh
[root@Node4 sh]# ll hello.sh
-rwxr-xr-x 1 root root 29 5月 16 14:00 hello.sh
#绝对路径启动脚本
[root@Node4 sh]#
[root@Node4 sh]# /root/sh/hello.sh
hello world
#调用解释器执行脚本
[root@Node4 sh]# bash hello.sh
hello world
#双引号:
[root@Node4 sh]# echo "$PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#单引号的使用
[root@Node4 sh]# echo '$PTAH'
$PTAH
#进行四则预算
[root@Node4 sh]# echo $[5*3]
15
[root@Node4 sh]# echo $[5+3]
8
#取命令结果
[root@Node4 sh]# touch $(date +%F)-haha.txt
[root@Node4 sh]# ll
总用量 20
-rw-r--r-- 1 root root 0 5月 16 14:05 2022-05-16-haha.txt
#取命令结果
[root@Node4 sh]# touch haha.txt_`date +%F`
#设置变量
[root@Node4 sh]# xx=haha
[root@Node4 sh]# echo $xx
haha
#更新复制
[root@Node4 sh]# xx=liangjiawei
[root@Node4 sh]# echo $xx
liangjiawei
变量的种类
#查看环境变量
[root@Node4 sh]# env
XDG_SESSION_ID=1
HOSTNAME=Node4
TERM=linux
SHELL=/bin/bash
.........
#获取变量
[root@Node4 sh]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#查看系统所有的变量
[root@Node4 sh]# set | grep $xx
xx=liangjiawei
位置变量的简介
$0 #脚本名称
$1 #第一个参数
$2 #第二个参数
$3 #第三个参数
$4 #第四个参数
$n… #第n个参数
预定义的变量讲解
$0 #代表脚本本身
$* #显示所有参数内容
$# #显示有多少个参数
$? #显示上一条命令的执行结果(
0代表正确,非0代表错误)
$$ #显示脚本进程号(PID)
#编写一个脚本
[root@Node4 sh]# vim aa.sh
#!/bin/bash
echo $0
echo $1
echo $2
echo $3
echo $*
echo $#
echo $$
echo $?
#然后执行以下脚本
[root@Node4 sh]# bash aa.sh liangjiawei zhangsan lisi
aa.sh
liangjiawei
zhangsan
lisi
liangjiawei zhangsan lisi
3
7487
0
#通过预位置变量来创建用户和设置密码
[root@Node4 sh]# vim useradd_v2.sh
#!/bin/bash
useradd $1 &> /dev/null
echo "用户创建成功~!"
echo $2 | passwd --stdin $1 &> /dev/null
echo "用户$1的密码设置成功,密码为$2"
#执行查看
[root@Node4 sh]# bash useradd_v2.sh ljw 1
用户创建成功~!
用户ljw的密码设置成功,密码为1
作用:读取用户在键盘上输入的内容,并且把内容放在变量里边;可以降低脚本的的使用难度
语法:read +选项
常用语法:read -p “提示信息” 变量名
#编写一个添加用户的脚本
[root@Node4 sh]# vim user_v1.sh
#!/bin/bash
read -p "请输入用户名字: " user
useraddd $user
echo "用户已经创建成功"
read -p "请输入用户的指定密码: " passwd
echo $passwd | passwd --stdin $user &> /dev/null
echo "用户密码创建成功~!"
#执行查看
[root@Node4 sh]# bash user_v1.sh
请输入用户名字: zzz
用户已经创建成功
请输入用户的指定密码: 1
用户密码创建成功~!
[root@Node4 sh]# id zzz
uid=1001(zzz) gid=1001(zzz) 组=1001(zzz)
[root@Node4 sh]#
#判断文件是否存在
[root@Node4 sh]# [ -e /etc/ ]
[root@Node4 sh]# echo $?
0 #取值为0代表为真,非0位假
#判断目录是否存在
[root@Node4 sh]# [ -d /opt ]
[root@Node4 sh]# echo $?
0
#判断文件是否存在
[root@Node4 sh]# [ -f /etc/fstab ]
[root@Node4 sh]# echo $?
0
#判断当前文件是否可读,当前用户身份
[root@Node4 sh]# [ -r /etc/shadow ]
[root@Node4 sh]# echo $?
0
[root@Node4 ~]# [ 1 -gt 12 ]
[root@Node4 ~]# echo $?
1
[root@Node4 ~]# [ 3 -ne 2 ]
[root@Node4 ~]# echo $?
0
[root@Node4 ~]# [ root == test ]
[root@Node4 ~]# echo $?
1
[root@Node4 ~]# [ $USER == root ]
[root@Node4 ~]# echo $?
0
[root@Node4 ~]# echo $[10+5]
15
[root@Node4 ~]# echo $[1*8]
8
#$(())做数值运算
[root@Node4 ~]# echo $((2*3))
6
[root@Node4 ~]# echo $((10/5))
2
#expr做数值运算
[root@Node4 ~]# echo expr 2+3
expr 2+3
#要求每一部分都要有空格
[root@Node4 ~]# echo `expr 2 + 3`
5
#当进行乘法运算时,需要实用“\”转义掉*的特殊功能
[root@Node4 ~]# echo `expr 10 * 3`
expr: 语法错误
[root@Node4 ~]# echo `expr 10 \* 3`
30
#let做数值运算
#需要将运算的结果赋予一个变量存储
[root@Node4 ~]# let x=1+1
[root@Node4 ~]# echo $x
2
#let简写表达式 #let完整表达式
let i++ let i=i+1
[root@Node4 ~]# let i++
[root@Node4 ~]# echo $i
1
[root@LiangGaRy ~]# i=10
[root@LiangGaRy ~]# echo $i
12
| let简写表达式 | let完整表达式 |
|---|---|
| let i++ | let i=i+1 |
| let i- - | let i=i-1 |
| let i+=2 | let i=i+2 |
| let i-=2 | let i=i-2 |
| let i*=2 | let i=i*2 |
| let i/=2 | let i=i/2 |
| let i%=2 | let i=i%2 |
#判断文件是否为真---> -z:是空才是真命题
[root@LiangGaRy ~]# [ -z /etc/passwd ]
[root@LiangGaRy ~]# echo $?
1
#-n:非空就是真命题
[root@LiangGaRy ~]# [ -n /etc/passwd ]
[root@LiangGaRy ~]# echo $?
0
#也可以用来判断变量是否为空
[root@LiangGaRy ~]# [ -z $i ]
[root@LiangGaRy ~]# echo $?
1