RHCE(第二部分)-----第七章:正则表达式

第七章、正则表达式

文本搜索工具---grep

grep(Global search REgular expression and Print out the line.)是一种强大的文本搜索工具,它能使用特定模式匹配(包括正则表达式)搜索文本,并默认输出匹配行。Unix的grep家族包括grep、egrepfgrep。Windows系统下类似命令FINDSTR

bash 复制代码
grep  [option...] 'pattern'  [FILENAME]
参数
-n  :显示行号
-o  :只显示匹配的内容
-q  :静默模式,没有任何输出,得用$?来判断执行成功没有,即有没有过滤到想要的内容
-l  :如果匹配成功,则只将文件名打印出来,失败则不打印,通常-rl一起用,grep -rl 'root' /etc 
-A  :如果匹配成功,则将匹配行及其后n行一起打印出来
-B  :如果匹配成功,则将匹配行及其前n行一起打印出来
-C  :如果匹配成功,则将匹配行及其前后n行一起打印出来
--color
-c  :如果匹配成功,则将匹配到的行数打印出来
-E  :等于egrep,扩展
-i  :忽略大小写
-v  :取反,不匹配
-w:匹配单词
-x 仅选择与整行完全匹配的匹配项。精确匹配每行内容(包括行首行尾看不到的空格内容)
-R -r以递归方式读取每目录下的文件
指定过滤器
--exclude-dir=  指定过滤目录,排除目录顾虑选择
[root@node1 ~]# grep   -rl  'aaa' /path  --exclude-dir=2  (注:直接写子路径)
--exclude-from=file指定过滤器文件,通过文件内容指定要排除的文件名

7.1 什么是正则表达式

​ 所谓正则表达式,实际上就是用来描述某些字符串匹配规则的工具。由于正则表达式语法简练,功能强大,得到了许多程序设计语言的支持,包括Java、C++、Perl以及Shell等。对于初学者来说,首次接触正则表达式非常难以接受,本节将介绍正则表达式的入门知识,以利于后面几节的学习。

7.2 为什么使用正则表达式

​ 在进行程序设计的过程中,用户会不可避免地遇到处理某些文本的情况。有的时候,用户还需要查找符合某些比较复杂规则的字符串。对于这些情况,如果单纯依靠程序设计语言本身,则往往会使得用户通过复杂的代码来来实现。但是,如果使用正则表达式,则会以非常简短的代码来完成。

7.3基本正则表达式

​ 基本正则表达式(Basic Regular Expression,BRE),又称为标准正则表达式,是最早制订的正则表达式规范,仅支持最基本的元字符集。基本正则表达式是POSIX规范制订的两种正则表达式语法标准之一,另外一种语法标准称为扩展正则表达式,将在随后介绍。

元字符 说明
^ 以某个字符开头
$ 以某个字符结尾
. 匹配任意单字符
* 对前一项进行0次或者多次重复匹配;匹配前一个字符任意次 .* : 匹配任意字符任意次
[] 对方括号内的单字符进行匹配 [a-z] [0-9] [[::]]
[^] 不匹配方括号内的单字符
^[1](#元字符 说明 ^ 以某个字符开头 $ 以某个字符结尾 . 匹配任意单字符 * 对前一项进行0次或者多次重复匹配;匹配前一个字符任意次 .* : 匹配任意字符任意次 [] 对方括号内的单字符进行匹配 [a-z] [0-9] [[::]] [^] 不匹配方括号内的单字符 1 匹配以某个字符开头的行 \b <或\b:锚定词首(支持vi和grep)其后面的任意字符必须作为单词首部出现;>或\b:锚定词尾 \s \S 匹配任何空白字符,包括空格、制表符(\t)、换行符(\n)、回车符(\r)、换页符(\f)等。在许多编程语言中,等价于 [ \t\n\r\f]。 \w \W 匹配字母、数字或下划线字符,通常等价于 [a-zA-Z0-9_]。在不同的正则表达式实现中,可能还会包括其他语言的字母字符。 \d \D \d:匹配一个数字字符,等价于 [0-9];\D:匹配任何非数字字符,是 \d 的反义。等价于 [^0-9])^ 匹配以某个字符开头的行
\b <或\b:锚定词首 (支持vi和grep)其后面的任意字符必须作为单词首部出现;>或\b:锚定词尾
\s \S 匹配任何空白字符,包括空格、制表符(\t)、换行符(\n)、回车符(\r)、换页符(\f)等。在许多编程语言中,等价于 [ \t\n\r\f]
\w \W 匹配字母、数字或下划线字符,通常等价于 [a-zA-Z0-9_]。在不同的正则表达式实现中,可能还会包括其他语言的字母字符。
\d \D \d:匹配一个数字字符,等价于 [0-9];\D:匹配任何非数字字符,是 \d 的反义。等价于 [^0-9]

-w 等同于 \b ;但是\b的精准度更高。

bash 复制代码
[root@localhost ~]# cat file
a
b
ba
baa
baaa
baaaa
baaaaba
baaaaaab

课堂案例:
[root@localhost day07]# grep '^root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost day07]# grep 'bash$' /etc/passwd
root:x:0:0:root:/root:/bin/bash
zhou:x:1000:1000:root:/home/zhou:/bin/bash
tom:x:1001:1001::/home/tom:/bin/bash
zhangsan:x:1002:1002::/home/zhangsan:/bin/bash
[root@localhost day07]# grep '^b.' file
ba
baa
baaa
baaaa
baaaaba
baaaaaab
[root@localhost day07]# grep '^b.*' file
b
ba
baa
baaa
baaaa
baaaaba
baaaaaab
[root@localhost ~]# grep '.*' file
[root@localhost ~]# grep [a-z]  /etc/passwd 
[root@localhost ~]# grep [^a-z]  /etc/passwd
[root@localhost day07]# grep '\bba\b' file
ba
[root@localhost day07]# grep '\<ba\>' file
ba

正则表达式练习:

练习一:
1、显示/proc/meminfo文 件中以不区分大小的s开头的行:
2、显示/etc/passwd中 以nologin结尾的行;
3、取出默认shell为/sbin/nologin的用户列表
4、取出默认shell为bash,且其用户ID号最小的用户的用户名

练习二:datafile内容如下
Steve Blenheim:238-923-7366:95 Latham Lane, Easton, PA 83755:11/12/56:20300
Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
Jon DeLoach:408-253-3122:123 Park St., San Jose, CA 04086:7/25/53:85100
Karen Evich:284-758-2857:23 Edgecliff Place, Lincoln, NB 92086:7/25/53:85100
Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
Fred Fardbarkle:674-843-1385:20 Parak Lane, DeLuth, MN 23850:4/12/23:780900
Fred Fardbarkle:674-843-1385:20 Parak Lane, DeLuth, MN 23850:4/12/23:780900
Lori Gortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
Paco Gutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500
Ephram Hardy:293-259-5395:235 CarltonLane, Joliet, IL 73858:8/12/20:56700
James Ikeda:834-938-8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
Barbara Kertz:385-573-8326:832 Ponce Drive, Gary, IN 83756:12/1/46:268500
Lesley Kirstin:408-456-1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
William Kopf:846-836-2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
Sir Lancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500
Jesse Neal:408-233-8971:45 Rose Terrace, San Francisco, CA 92303:2/3/36:25000
Zippy Pinhead:834-823-8319:2356 Bizarro Ave., Farmount, IL 84357:1/1/67:89500
Arthur Putie:923-835-8745:23 Wimp Lane, Kensington, DL 38758:8/31/69:126000
Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350
Jose Santiago:385-898-8357:38 Fife Way, Abilene, TX 39673:1/5/58:95600
Tommy Savage:408-724-0140:1222 Oxbow Court, Sunnyvale, CA 94087:5/19/66:34200
Yukio Takeshida:387-827-1095:13 Uno Lane, Ashville, NC 23556:7/1/29:57000
Vinh Tranh:438-910-7449:8235 Maple Street, Wilmington, VM 29085:9/23/63:68900

1、显示包含 San的行
2、显示以 J 开头的人名所在的行
3、显示 700 结尾的行
4、显示不包 834 的行   
5、显示生日 12 月的行
6、显示电话号码的区号为 834 的行
7、显示这样的行 : 它包含一个大写字母后跟四个小写字母 , 逗号, 空格, 和一个大写字母
8、显示姓以 K或 k 开头的行
9、显示工资为六位数的行 , 并在前面加行号
10、显示包括 Lincoln 或 lincoln 的行, 并且 grep 对大小写不敏感

显示/etc/grub2.cfg 文件中,至少以一个空白字符开头的且后面存非空白字符的行
找出"netstat -tan"命令的结果中以'LISTEN'后跟0个、1个或多个空白字符结尾的行
使用egrep 取出/etc/rc.d/init.d/functions路径名
找出ifconfig 命令结果中本机的IPv4 地址
[root@localhost ~]# ifconfig | grep -E -o  "\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-1][0-9]|22[0-3])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){2}\.([2-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>"
192.168.220.154
找出"fdisk  -l"命令的结果中,包含以/dev/后跟sd或hd及一个小字母的行;

7.4扩展正则表达式

扩展正则表达式(Extended Regular Expression,ERE)支持比基本正则表达式更多的元字符,但是扩展正则表达式对有些基本正则表达式所支持的元字符并不支持。前面介绍的元字符"^"、"$"、"."、"*"、"[]"以及"[^]"这6个元字符在扩展正则表达式都得到了支持,并且其意义和用法都完全相同,不再重复介绍。接下来重点介绍一下在扩展正则表达式中新增加的一些元字符。

正则符号 描述
+ 匹配前一个最少匹配1次 1-任意次
匹配前一个最多匹配1次 0次或者一次
{n,m} 匹配前一个匹配n-m次 {1,} {,1}
() \1\2 组合为整体、保留
| 或者 [10...20] 1[0...9]|20
后项引用:后面例子中会用到。
分组:
    (abc)(123)asd\1fgh\2jkl
        (ab)*
        向后引用符:
        \1:引用第一个左括号以及与之对应的右括号所包括的所有内容
        \2:
        \3:

课堂案例:
[root@localhost ~]# grep -E  'ba+' file
[root@localhost ~]# grep -E  'ba?' file
[root@localhost ~]# grep -E  'ba{2,3}' file
[root@localhost ~]# grep -E '^([a-z]{2}).*[a-z]{2}$' file
baaa
baaaa
baaaaba
baaaaaab
[root@localhost ~]# grep -E '^([a-z]{2}).*\1' file
baaaaba
[root@localhost ~]# grep 'root|euler' /etc/passwd
bash 复制代码
练习题三: file.txt文件内容:
48   Dec    3BC1977    LPSX    68.00   LVX2A   138
483 Sept   5AP1996     USP    65.00   LVX2C   189
47    Oct      3ZL1998    LPSX   43.00   KVM9D 512
219  dec      2CC1999  CAD     23.00   PLV2C    68
484  nov      7PL1996   CAD    49.00     PLV2C  234
483   may     5PA1998  USP     37.00    KVM9D  644
216   sept      3ZL1998  USP     86.00    KVM9E   234

# 1,含有"48"字符串的行的总数
[root@localhost day07]# grep -c '48' file.txt 
4
# 2,显示含有"48"字符串的所有行的行号
[root@localhost day07]# grep -n '48' file.txt 
1:48   Dec    3BC1977    LPSX    68.00   LVX2A   138
2:483 Sept   5AP1996     USP    65.00   LVX2C   189
5:484  nov      7PL1996   CAD    49.00     PLV2C  234
6:483   may     5PA1998  USP     37.00    KVM9D  644 
# 3,精确匹配只含有"48"字符串的行
[root@localhost day07]# grep -x '48' file.txt
# 4,抽取代码为484和483的城市位置
[root@localhost day07]# grep -E '484|483' file.txt 
483 Sept   5AP1996     USP    65.00   LVX2C   189
484  nov      7PL1996   CAD    49.00     PLV2C  234
483   may     5PA1998  USP     37.00    KVM9D  644
[root@localhost day07]# grep -E '^(484|483)' file.txt 
# 5,显示行首不是4或8
[root@localhost day07]# grep -E '^[^4|8]' file.txt 
219  dec      2CC1999  CAD     23.00   PLV2C    68
216   sept      3ZL1998  USP     86.00    KVM9E   234
# 6,显示含有九月份(Sept)的行
[root@localhost day07]# grep -i 'Sept' file.txt
483 Sept   5AP1996     USP    65.00   LVX2C   189
216   sept      3ZL1998  USP     86.00    KVM9E   234
# 7,显示以K开头、以D结尾的所有代码
[root@localhost day07]# grep -E 'K.*D' file.txt 
47    Oct      3ZL1998    LPSX   43.00   KVM9D 512
483   may     5PA1998  USP     37.00    KVM9D  644
[root@localhost day07]# grep -E '\bK.*D\b' file.txt 
47    Oct      3ZL1998    LPSX   43.00   KVM9D 512
483   may     5PA1998  USP     37.00    KVM9D  644
# 8,显示头两个是大写字母,中间至少两个任意,并以C结尾的代码
[root@localhost day07]# grep -E '\b[A-Z]{2}.{2,}C\b' file.txt 
483 Sept   5AP1996     USP    65.00   LVX2C   189
219  dec      2CC1999  CAD     23.00   PLV2C    68
484  nov      7PL1996   CAD    49.00     PLV2C  234
grep -wE '[A-Z]{2}[a-zA-Z]{2,}C'  file.txt
# 9,查询单词所有以5开始以1996或1998结尾的所有记录  
[root@localhost day07]# grep -E '\b5.*(1996|1998)\b' file.txt 
483 Sept   5AP1996     USP    65.00   LVX2C   189
483   may     5PA1998  USP     37.00    KVM9D  644
bash 复制代码
练习题四:
1、显示/etc/passwd文件中以bash结尾的行;
2、找出/etc/passwd文件中的三位或四位数;
3、找出/etc/grub2.cfg文件中,以至少一个空白字符开头,后面又跟了非空白字符的行
4、找出"netstat  -tan"命令的结果中,以'LISTEN'后跟0或多个空白字符结尾的行;
5、找出"fdisk  -l"命令的结果中,包含以/dev/后跟sd或hd及一个字母的行;
6、找出"ldd  /usr/bin/cat"命令的结果中文件路径;
7、找出/proc/meminfo文件中,所有以大写或小写s开头的行;至少用三种方式实现;
8、显示当前系统上root、centos或spark用户的相关信息;
9、echo输出一个绝对路径,使用egrep取出其基名;
10、找出ifconfig命令结果中的1-255之间的整数;
11、找出系统中其用户名与shell名相同的用户。
[root@172 ~]# grep '^\(.*\):.*\1$' /etc/passwd
[root@172 ~]# egrep  '(^[[:alpha:]]+)\b.*\1$' /etc/passwd 
    He love his lover.
    She like her liker.
    He like his lover.
    She love her liker.

作业:

1、显示/etc/rc.d/rc.sysinit文件中以不区分大小的h开头的行;
egrep -i '^h' /etc/rc.d/rc.sysinit
egrep 'h|H' /etc/rc.d/rc.sysinit
egrep '[hH]' /etc/rc.d/rc.sysinit
2、显示/etc/passwd中以sh结尾的行;
grep -E 'sh$'   /etc/passwd
3、显示/etc/fstab中以#开头,且后面跟一个或多个空白字符,而后又跟了任意非空白字符的行;
grep -E '^#[[:space:]]+[^[:space:]]*'  /etc/fstab
grep -E  '^#\s+\S*'  /etc/fstab
grep -E '^# +[^ ]*'  /etc/fstab
4、查找/etc/rc.d/rc.local中包含"以to开始并以to结尾"的字串行;
egrep '\b(to).*\1\b' /etc/rc.d/rc.local
5、查找/etc/inittab中含有"以s开头,并以d结尾的单词"模式的行;
grep -w 's.*d' /etc/inittab
6、查找ifconfig命令结果中的1-255之间的整数;
ifconfig | egrep -ow '[1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5]' 
ifconfig | egrep -ow '[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-5][0-5]'
7、显示/var/log/secure文件中包含"Failed"或"FAILED"的行
8、在/etc/passwd中取出默认shell为bash
9、以长格式列出/etc/目录下以ns开头、.conf结尾的文件信息
ls /etc| grep '\bns.*.conf\b'
10、高亮显示passwd文件中冒号,及其两侧的字符
egrep '.:.'   /etc/passwd
11、匹配/etc/services中行开头结尾一样的单词
egrep '(\b[a-zA-Z]+\b).*\b\1' /etc/services
12、显示/etc/inittab中 以#开头,且后面跟-一个或多个空白字符,而后又跟了任意非空白字符的行
egrep  '^#[[:space:]]+\[^[:space:]]*'   /etc/inittab
egrep '^#\s+\S{,}' /etc/inittab
13、显示/etc/inittab中包含 了:一个数值 (即两个冒号中间一个数字的行
/etc/passwd   多个冒号之间的数值匹配显示
egrep '(:[0-9]+)+:' passwd
14、显示/boot/grub2/grub.cfg文件中以一个或多个空白字符开头的行:
egrep "^\s+" /boot/grub2/grub.cfg 
 egrep "^[[:space:]]+" /boot/grub2/grub.cfg
15、显示/etc/inittab文件中以一个数字开头并以一个与开头数字相同的数字结尾的行;
egrep '^([0-9]).*\1$' passwd
16、找出/proc/cpuinfo中的,1位数,或2位数;
egrep -v '(\.[0-9]+)|([0-9]+\.)' /proc/cpuinfo  | egrep '\b[0-9]{1,2}\b' | wc -l
17、查找当前系统上名字为student(必须出现在行首)的用户的账号的相关信息,文件为/etc/passwd
[root@localhost test]# egrep '^root\b' passwd
root:x:0:root:/root:/bin/bash1
[root@localhost test]# egrep '^root\>' passwd
root:x:0:root:/root:/bin/bash1
[root@localhost test]# grep -w  '^root' passwd
root:x:0:root:/root:/bin/bash1

正则匹配的贪婪模式:


  1. ↩︎
相关推荐
MC何失眠10 分钟前
vulnhub靶场【Raven系列】之2 ,对于mysql udf提权的复习
linux·网络·数据库·mysql·web安全·网络安全
JhonKI1 小时前
【Linux】gdb_进程概念
linux·运维·服务器
航月1 小时前
linux系统监视(centos 7)
linux·运维·centos
GISMagic5 小时前
正则表达式学习网站
正则表达式
等一场春雨5 小时前
Java21 正则表达式
正则表达式
周杰伦_Jay9 小时前
Ubuntu20.4和docker终端指令、安装Go环境、安装搜狗输入法、安装WPS2019:保姆级图文详解
linux·python·ubuntu·docker·centos
Danileaf_Guo9 小时前
Ubuntu磁盘空间不足或配置错误时,如何操作扩容?
linux·运维·服务器·ubuntu
Linux运维老纪9 小时前
K8s 集群 IP 地址管理指南(K8s Cluster IP Address Management Guide)
linux·运维·tcp/ip·容器·kubernetes·云计算·运维开发
大大菜鸟一枚9 小时前
arm使用ubi系统
linux·arm开发·学习
鸭梨山大。9 小时前
ubuntu安全配置基线
linux·安全·ubuntu