case语句
case语句为多选择语句。
可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。
case $var in 匹配变量值;var代表是变量名
pattern 1) 模式1;可以匹配多个模式,多个模式之间用 | 分隔
command1 需要执行的语句
;; 两个分号代表命令结束
pattern 2)
command2
;;
pattern 3)
command3
;;
*) default,不满足以上模式,默认执行*)下面的语句
command4
;;
esac esac表示case语句结束
应用案例1——熟悉case语句的基本语法结构
1、当给程序传入start、stop、reload三个不同参数时分别执行相应命令。
#!/bin/bash
case $1 in
start|S)
echo "service is running...."
;;
stop|T)
echo "service is stoped..."
;;
reload|R)
echo "service is restart..."
;;
*)
echo "请输入你要的动作"
;;
esac
或者
#!/bin/bash
read -p "请输入你要的动作:" action
case $action in
start|S)
echo "service is running...."
;;
stop|T)
echo "service is stoped..."
;;
reload|R)
echo "service is restart..."
;;
*)
echo "请输入你要的动作"
;;
esac
2、脚本提示让用户输入需要管理的服务名,然后提示用户需要对服务做什么操作,如启动,关闭,重启等
#!/bin/bash
read -p "请输入需要管理的服务名称(vsftpd):" service
case $service in
vsftpd)
read -p "请输入要操作的动作:" action
case $action in
start|S)
service vsftpd start
;;
stop|P)
service vsftpd stop
;;
reload|restart|R)
service vsftpd reload
;;
esac
;;
httpd)
echo "apache is running..."
;;
*)
echo "请输入需要管理的服务名称(vsftpd):"
;;
esac
应用案例2——菜单打印
模拟一个多任务维护界面。
当执行程序时先显示总菜单,然后进行选择后做相应维护监控操作。
总菜单
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
分析
1. 打印菜单 echo cat
[root@bobilinux shell]# cat case.sh
#!/bin/bash
echo -e "h 显示命令帮助\nf 显示磁盘分区\nd 显示磁盘挂载\nm 查看内存使用\nu 查看系统负载\nq 退出程序"
[root@bobilinux shell]# chmod +x case.sh
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
[root@bobilinux shell]# cat case.sh
#!/bin/bash
#echo -e "h 显示命令帮助\nf 显示磁盘分区\nd 显示磁盘挂载\nm 查看内存使用\nu 查看系统负载\nq 退出程序"
cat <<-EOF
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
EOF #EOF前要有制表符(tab),如果上面的EOF前面没有-,那这里的EOF要顶格写
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
2. 等待用户输入需要的操作编号 read
3. 根据用户输入的操作编号执行相应的操作命令 case
脚本
#!/bin/bash
#打印菜单
cat <<-EOF
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
EOF
#让用户输入需要的操作
read -p "请输入需要操作的选项[h help]:" option
case $option in
h)
cat <<-EOF
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
EOF
;;
f)
fdisk -l
;;
d)
df -h
;;
m)
free -m
;;
u)
uptime
;;
q)
exit
;;
esac
执行结果
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
请输入需要操作的选项[h help]:h
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
请输入需要操作的选项[h help]:m
total used free shared buffers cached
Mem: 1861 173 1688 0 46 36
-/+ buffers/cache: 90 1771
Swap: 999 0 999
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
请输入需要操作的选项[h help]:u
12:17:47 up 1:41, 2 users, load average: 0.00, 0.00, 0.00
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
请输入需要操作的选项[h help]:q
[root@bobilinux shell]#
脚本优化
1、脚本中有重复出现的部分,可以把该部分定义成一个函数,重复出现的部
分作为函数体,每次需要应用重复的部分时,直接调用该函数
2、不希望每次操作时都要运行该脚本,希望操作一次后可以继续一直操作,
想退出的时候再退出,这个时候,需要借助 while true 死循环,但是要确
保死循环有结束的条件
3、优化执行的命令,清晰的看结果
#!/bin/bash
#打印菜单
menu(){
cat <<-END
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
END
}
menu
while true
do
read -p "请输入你的操作[h help]:" var1
case $var1 in
h)
menu
;;
f)
read -p "请输入你要查看的设备名字[/dev/sdb]:" var2
case $var2 in
/dev/sda)
fdisk -l /dev/sda
;;
/dev/sdb)
fdisk -l /dev/sdb
;;
esac
;;
d)
df -h
;;
m)
free -m
;;
u)
uptime
;;
q)
exit
;;
esac
done
执行结果
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
请输入你的操作[h help]:h
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
请输入你的操作[h help]:f
请输入你要查看的设备名字[/dev/sdb]:/dev/sda
Disk /dev/sda: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00089914
Device Boot Start End Blocks Id System
/dev/sda1 * 1 26 204800 83 Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2 26 154 1024000 82 Linux swap / Solaris
Partition 2 does not end on cylinder boundary.
/dev/sda3 154 1306 9255936 83 Linux
请输入你的操作[h help]:d
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 8.7G 1.8G 6.5G 22% /
tmpfs 931M 0 931M 0% /dev/shm
/dev/sda1 194M 34M 151M 19% /boot
请输入你的操作[h help]:m
total used free shared buffers cached
Mem: 1861 173 1688 0 46 36
-/+ buffers/cache: 90 1771
Swap: 999 0 999
请输入你的操作[h help]:u
12:29:41 up 1:53, 2 users, load average: 0.00, 0.00, 0.00
请输入你的操作[h help]:q
[root@bobilinux shell]#
练习1
模拟2人第一次相亲的场景,使用read让用户输入它的名字,性别,年龄(年
龄放在性别判断后)
要求:
1)
• 对性别进行判断,如果不输入男或者女,则显示”你是泰国来的吗?“
• 如果是男的,对其年龄进行判断。
2)
• 如果男的年龄大于等于18岁则显示“某某先生,你结婚了吗?”;
• 如果对方回答结了或者yes,则显示“结了你来这凑什么热闹”;
• 如果对方回答没有或者no,再次询问“那你有房有车吗?”;
• 如果既不说结了也不说没结则显示:“你到底结没结婚啊?”
• 如果回答有房有车,则显示”咱去民政局领证吧“;
• 如果回答没有,则显示“不好意思,我去下洗手间。”;
• 如果既不说有又不说没有,则显示“别浪费时间,请正面回答”。
• 如果男的年龄小于18岁,则显示“某某某你个小毛孩也来这凑热闹啦”
3)如果是女的,并且年龄大于等于18岁,则显示”某某女士你好“;否则显示”某某小姐你好“
参考:
#!/bin/bash
read -p "输入你的姓名:" name
read -p "输入你的性别:" gender
case "$gender" in
男|man|male|boy )
read -p "输入你的年龄:" age
if [ $age -ge 18 ];then
read -p "$name先生,你结婚了吗?" anwser
case "$anwser" in
结了|有|yes )
echo "结了你还来干嘛?"
;;
没结|没有|没|no )
read -p "有房有车吗?" anwser2
case "$anwser2" in
有)
echo "咱就直接去民政局领证吧"
;;
没有 )
echo "不好意思,我去下洗手间"
;;
* )
echo "别浪费时间,请正面回答"
esac
;;
* )
echo "你到底结没结?"
esac
else
echo "$name小子"
fi
;;
女|woman|female|girl|lady )
read -p "输入你的年龄:" age
if [ $age -ge 18 ];then
echo "$name女士"
else
echo "$name小姐"
fi
;;
* )
echo "你是泰国来的吗?"
esac
函数
shell中允许将一组命令集合或语句形成一段可用代码,这些代码块称为shell函数。给这段代码起个名字称为函数名,后续可以直接调用该段代码的功能。
函数的定义
函数名()
{
函数体(一堆命令的集合,来实现某个功能)
}
或者
function 函数名()
{
函数体(一堆命令的集合,来实现某个功能)
}
函数的调用
当前命令行调用
只在当前命令行有效,退出重新登录或复制会话后的命令行都无法调用
1、将函数写入 shell 脚本中
[root@MissHou shell04]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello lilei $1"
hostname
}
menu(){
cat <<EOF
1. mysql
2. web
3. app
4. exit
EOF
}
2、source shell.sh,使其生效
[root@MissHou shell04]# source fun1.sh
3、在当前命令行可以直接调用脚本中的函数
[root@bobilinux shell]# menu
1. mysql
2. web
3. app
4. exit
退出重新登录:
[root@bobilinux shell]# exit
logout
Connection closed.
Disconnected from remote host(CentOS 6.5) at 15:24:45.
Type `help' to learn how to use Xshell prompt.
[C:\~]$
[C:\~]$
[C:\~]$
[C:\~]$
Connecting to 192.168.192.131:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
WARNING! The remote SSH server rejected X11 forwarding request.
Last login: Sun May 8 15:22:57 2022 from 192.168.192.1
[root@bobilinux ~]#
[root@bobilinux ~]#
[root@bobilinux ~]# menu
-bash: menu: command not found 调用失败
复制会话:
[root@bobilinux shell]# menu
-bash: menu: command not found 调用失败
定义到全局的/etc/bashrc文件中或用户的~/.bashrc文件中
将函数写到 /etc/bashrc 或 ~/.bashrc 文件中,通过 source /etc/bashrc 使
其生效后,该函数将永久生效(无论是重新登陆后还是复制会话后的命令行)
[root@bobilinux ~]# tail -10 /etc/bashrc
menu(){
cat <<EOF
1. mysql
2. web
3. app
4. exit
EOF
}
[root@bobilinux ~]# source /etc/bashrc
[root@bobilinux ~]# menu
1. mysql
2. web
3. app
4. exit
退出重新登录:
[root@bobilinux ~]# exit
logout
Connection closed.
Disconnected from remote host(CentOS 6.5) at 15:32:58.
Type `help' to learn how to use Xshell prompt.
[C:\~]$
Connecting to 192.168.192.131:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.
WARNING! The remote SSH server rejected X11 forwarding request.
Last login: Sun May 8 15:32:02 2022 from 192.168.192.1
[root@bobilinux ~]#
[root@bobilinux ~]# menu
1. mysql
2. web
3. app
4. exit
复制会话:
[root@bobilinux ~]# menu
1. mysql
2. web
3. app
4. exit
注意:
当用户打开bash的时候会读取该文件
脚本中调用
该函数只在当前脚本中有效,无法在终端调用
[root@bobilinux shell]# cat case.sh
#!/bin/bash
#打印菜单
menu(){
cat <<-END
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
END
}
menu //调用函数
[root@bobilinux shell]# ./case.sh
h 显示命令帮助
f 显示磁盘分区
d 显示磁盘挂载
m 查看内存使用
u 查看系统负载
q 退出程序
[root@bobilinux shell]# menu
-bash: menu: command not found
脚本中调用优化
我们可以把函数都写在一个函数文件里面,在shell脚本中需要调用这个函数的
时候,不需要重新在定义一遍,在脚本里面通过 source 全路径函数文件 后,
就可以直接在脚本中调用函数而不需要重新定义了
[root@bobilinux ~]# cd /tmp/shell/
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
hostname
}
menu(){
cat <<EOF
1. mysql
2. web
3. app
4. exit
EOF
}
[root@bobilinux shell]# cat case.sh
#!/bin/bash
source /tmp/shell/fun1.sh 全路径函数文件
#调用函数文件中的函数
hello
menu
[root@bobilinux shell]# ./case.sh
hello world
bobilinux
1. mysql
2. web
3. app
4. exit
函数中return
1、return可以结束一个函数,类似于前面讲的循环控制语句break
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
return
hostname
}
[root@bobilinux shell]# source fun1.sh
[root@bobilinux shell]# hello
hello world
2、return默认返回函数中最后一个命令的退出状态(用于判定最后一个命令是否正确执行),也可以给定参数值,该参数值的范围是0-256之间
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
hostname
return
}
[root@bobilinux shell]# source fun1.sh
[root@bobilinux shell]# hello
hello world
bobilinux
[root@bobilinux shell]# echo $? #return无参数,$?默认是最后一个命令hostname的执行状态
0
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
hostname
return 2
}
[root@bobilinux shell]# source fun1.sh
[root@bobilinux shell]# hello
hello world
bobilinux
[root@bobilinux shell]# echo $? #return有参数,$?就是该参数
2
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
hostname
return 2
if [ $? -eq 2 ];then
echo hahaha
fi
}
[root@bobilinux shell]# source fun1.sh
[root@bobilinux shell]# hello
hello world
bobilinux
[root@bobilinux shell]# echo $?
2
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
hostname
return 2
}
hello
if [ $? -eq 2 ];then
echo hahahaha
fi
[root@bobilinux shell]# chmod +x fun1.sh
[root@bobilinux shell]# bash -x ./fun1.sh
+ hello
+ echo 'hello world'
hello world
+ hostname
bobilinux
+ return 2
+ '[' 2 -eq 2 ']'
+ echo hahahaha
hahahaha
[root@bobilinux shell]# ./fun1.sh
hello world
bobilinux
hahahaha
3、如果没有return命令,函数将返回最后一个命令的退出状态
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
hostname
}
[root@bobilinux shell]# source fun1.sh
[root@bobilinux shell]# hello
hello world
bobilinux
[root@bobilinux shell]# echo $?
0
[root@bobilinux shell]# cat fun1.sh
#!/bin/bash
hello(){
echo "hello world"
hostnamee
}
[root@bobilinux shell]# source fun1.sh
[root@bobilinux shell]# hello
hello world
-bash: hostnamee: command not found
[root@bobilinux shell]# echo $?
127
应用案例1
需求:写一个脚本让用户输入基本信息(姓名,性别,年龄),如不输入一直提示输入,最后根据用户的信息输出相对应的内容
思路:
循环直到输入字符串不为空 (该功能可以定义为一个函数,方便下面脚本调用)
根据用户输入信息做出匹配判断 case 语句
脚本:
#!/bin/bash
#该函数实现用户如果不输入内容则一直循环直到用户输入为止,并且将用户输入的内容打印出来
input_fun()
{
input_var=""
output_var=$1 #调用该函数时,后面接的第一个参数(如 input_fun 请输入你的姓名:)
while [ -z $input_var ]
do
read -p "$output_var" input_var
done
echo $input_var
}
或者
#!/bin/bash
fun(){
read -p "$1" name
if [ -z $name ];then
fun $1
else
echo $name
fi
}
#调用函数并且获取用户的姓名、性别、年龄分别赋值给name、sex、age变量
name=$(input_fun 请输入你的姓名:)
sex=$(input_fun 请输入你的性别:)
age=$(input_fun 请输入你的年龄:)
#根据用户输入的性别进行匹配判断
case $sex in
man)
if [ $age -gt 18 -a $age -le 35 ];then
echo "中年大叔你油腻了吗?加油"
elif [ $age -gt 35 ];then
echo "保温杯里泡枸杞"
else
echo "年轻有为。。。"
fi
;;
woman)
xxx
;;
*)
xxx
;;
esac
调用函数的时候可以传参数,这个参数在函数内部可以用 $1 $2 替代
应用案例2
需求:实现Nginx 服务自启动
思路:
要在/etc/init.d/目录下编写 Nginx 的启动脚本 nginxd
cd /etc/init.d/
vim nginxd
脚本:
#!/bin/bash
nginx=/usr/local/nginx/sbin/nginx
start(){
echo "nginx starting .... [OK] "
$nginx
}
start
脚本执行:
脚本优化:
#!/bin/bash
nginx=/usr/local/nginx/sbin/nginx
start(){
echo "nginx starting .... [OK] "
$nginx
}
status(){
if `ss -antpl | grep nginx > /dev/null`
then echo "nginx starting .... "
else echo "nginx stoping .... "
fi
}
stop(){
echo "nginx stoping .... [OK] "
$nginx -s stop
}
case $1 in
start)
start
;;
stop)
stop
;;
restart
stop
start
;;
*)
echo "Usage :$0 {start|stop|restart}"
esac
脚本执行:
接下来,让它永久启动
打开我们编写好的nginxd脚本,添加下面两行
# chkconfig: - 84 18
# description: nginx script
加入chkconfig list
chkconfig --add nginxd
默认都是关闭的 off
我们将 5 级别打开 on
chkconfig --list nginxd on
接下来,重启操作系统
reboot
可以看到, nginx 已经自启动了
综合案例
任务/背景
现有的跳板机虽然实现了统一入口来访问生产服务器,yunwei用户权限太大可
以操作跳板机上的所有目录文件,存在数据被误删的安全隐患,所以希望你做
一些安全策略来保证跳板机的正常使用。
具体要求
1、只允许yunwei用户通过跳板机远程连接后台的应用服务器做一些维护操作
2、公司运维人员远程通过yunwei用户连接跳板机时,跳出以下菜单供选择:
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master(centos8)
2. DB2-Slave(centos6)
3. Web1
4. Web2
h. help
q. exit
3、当用户选择相应主机后,直接免密码登录成功
4、如果用户不输入一直提示用户输入,直到用户选择退出
分析
1、打印菜单——>定义函数 echo cat
2、让用户选择需要操作的机器 case....esac
3、配置免密登录
4、每个菜单提供功能==——>case...esac用户选择做的事情
5、循环让用户输入选择
6、每个功能写成函数——>不是必须
7、脚本放的位置——>yunwei用户的家目录(执行命令放在 ~/.bashrc 中,一登录就打印菜单,执行脚本)
脚本
在此之前,要确保跳板机可以实现免密登录
#!/bin/bash
# jumper-server
# 定义菜单打印功能的函数
menu1()
{
cat <<-EOF
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master(centos8)
2. DB2-Slave(centos6)
3. Web(centos8)
h. help
q. exit
EOF
}
menu2()
{
cat <<-EOF
欢迎使用web-server,请选择你要操作的内容:
1. 清理日志
2. 启动apache
3. 重启apache
h. help
q. 退出
EOF
}
# 调用函数来打印菜单
menu1
while true
do
# 菜单选择,case...esac语句
read -p "请选择你要访问的主机(h help):" host
case $host in
1)
ssh root@192.168.192.130
;;
2)
ssh root@192.168.192.131
;;
3)
clear
menu2
read -p "请输入你要操作的内容(h help):" action
case $action in
1)
ssh root@192.168.192.130 echo "日志正在清理中..."
;;
2)
ssh root@192.168.192.130 echo "apache is running..."
;;
3)
ssh root@192.168.192.130 service apache restart
;;
h)
menu2
;;
q)
echo ""
;;
esac
menu1
;;
h)
clear
menu1
;;
q)
exit
;;
esac
done
脚本位置
1、脚本放在 yunwei 用户的家目录下(在家目录下操作不用 sudo)
2、为了让yunwei用户一登录就进入到菜单里面(限制权限,yunwei用户只能
做菜单中规定的事情),需要把执行该脚本的命令放到 ~/.bashrc 文件里面
(用户一登录就会读取这个文件里面的内容)
[yunwei@bobi ~]$ tail -2 .bashrc
bash jumper-server.sh
exit #用户一从菜单里退出,就会断开链接,重新登录后又会进入到菜单中
实例:
[root@bobi ~]# su - yunwei
Last login: Sun May 8 19:23:59 CST 2022 on pts/1
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master(centos8)
2. DB2-Slave(centos6)
3. Web(centos8)
h. help
q. exit
请选择你要访问的主机:2
Last login: Sun May 8 19:24:04 2022 from 192.168.192.145
[root@bobilinux ~]# exit
logout
Connection to 192.168.192.131 closed.
请选择你要访问的主机:
请选择你要访问的主机:q
[root@bobi ~]#
[root@bobi ~]# su - yunwei
Last login: Sun May 8 19:26:08 CST 2022 on pts/1
欢迎使用Jumper-server,请选择你要操作的主机:
1. DB1-Master(centos8)
2. DB2-Slave(centos6)
3. Web(centos8)
h. help
q. exit
请选择你要访问的主机:
但是还有个问题
用户直接 CTRL + C 退出当前菜单,这时候发现也能退到 yunwei 用户
请选择你要访问的主机:^C[yunwei@bobi ~]$
[yunwei@bobi ~]$
[yunwei@bobi ~]$
怎么办?
脚本优化
需要在脚本中通过 trap 命令来屏蔽这个 CTRL+C 的信号(在脚本首部添加)
# 捕捉到 1 2 3 19 的信号什么都不做
trap '' 1 2 3 19
补充:
1) SIGHUP 重新加载配置
2) SIGINT 键盘中断^C
3) SIGQUIT 键盘退出
9) SIGKILL 强制终止
15) SIGTERM 终止(正常结束),缺省信号
18) SIGCONT 继续
19) SIGSTOP 停止
20) SIGTSTP 暂停^Z
正则表达式
什么是正则表达式
正则表达式(Regular Expression、regex或regexp,缩写为RE),也译为正规表示法、常规表示法,是一种字符模式,用于在查找过程中匹配指定的字符。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。
支持正则表达式的程序如:locate |find| vim| grep| sed |awk
专有名词
元字符:在正则中,具有特殊意义的专用字符 . *
前导字符:元字符前面的字符叫前导字符
基础的正则表达式
正常匹配正则表达式
(1). 任意单个字符,除了换行符
(2)* 前导字符出现0次或多次
(3).* 任意长度的字符
(4)^ 行的开头
(5)$ 行的结尾
(6)^$ 空行
(7)[] 匹配指定字符组内的任一单个字符 [abc]
(8)[^] 匹配不在指定字符组内的任一字符 [^abc]
(9)^[] 匹配以指定字符组内的任一字符开头 ^[abc]
(10)^[^] 匹配不以指定字符组内的任一字符开头 ^[^abc]
(11)\< 取单词的头
(12)\> 取单词的尾
(13)\<\> 精确匹配单词 \<hello\> grep -w 'hello'
(14)\{n\} 匹配前导字符连续出现n次 go\{2\} google gooogle
(15)\{n,\} 匹配前导字符至少出现n次
(16)\{n,m\} 匹配前导字符出现n次与m次之间
(17) \(strings\) 保留匹配到的字符
Perl内置正则
正则表达式前加 -P
\d 匹配数字 [0-9]
\w 匹配字母数字下划线[a-zA-Z0-9_]
\s 匹配空格、制表符、换页符[\t\r\n]
#grep -P '\d' test.txt
#grep -P '\w' test.txt
#grep -P '\s' test.txt
扩展类的正则表达式
需要使用 grep -E (egrep )或 sed -r 进行匹配
+ 匹配一个或多个前导字符
? 匹配零个或一个前导字符
a|b 匹配a或b
() 组字符 hello myself yourself (my|your)self
{n} 前导字符重复n次 \{n\}
{n,} 前导字符重复至少n次 \{n,\}
{n,m} 前导字符重复n到m次 \{n,m\}
# egrep "root|ftp|adm" /etc/passwd
# grep -E "root|ftp|adm" /etc/passwd
# grep -E 'o+gle' test.txt
# grep -E 'o?gle' test.txt
# egrep 'go{2,}' 1.txt
# egrep '(my|your)self' 1.txt
grep 匹配模式选择
grep --help:
匹配模式选择:
Regexp selection and interpretation:
-E, --extended-regexp 扩展正则
-G, --basic-regexp 基本正则
-P, --perl-regexp 调用perl的正则
-e, --regexp=PATTERN use PATTERN for matching
-f, --file=FILE obtain PATTERN from FILE
-i, --ignore-case 忽略大小写
-w, --word-regexp 匹配整个单词