5: 正则表达式 + 三剑客之grep
1 正则表达式
正则表达式元字符分类:
- 字符匹配
- 次数匹配
- 位置锚定
- 分组
基本正则表达式: vim, grep,awk, sed
扩展正则表达式: grep,sed
1.1 基本正则表达式元字符
1.1.1 字符匹配
. 匹配任意单个字符, 可以是一个汉字或者标点符合
[] 匹配指定范围内的任意单个字符, 括号内可以是多种组合 示例: [wang] [0-9] [a-z] [a-zA-Z], 如[0-9.]表示包含数字0-9或.的行
#注意: 正则表达式中的[a-z]就是匹配连续的小写字母, 而通配符是按字典顺序,aAbB...去匹配
#正则表达式如果需要匹配大写字母和小写字母, 用[a-z][A-Z],或[:alpha:]
[^] 匹配指定范围外的任意单个字符, 示例: [^wang]
[:alpha:] 代表任何英文大小写字符, 即 A-Z, a-z
[:alnum:] 字母和数字
[:lower:] 小写字母, 示例: [[:lower:]], 相当于 [a-z]
[:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符, (比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格, 删除, 警铃...)
[:digit:] 十进制数字
[:xdigit:] 十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
举例 1:
图片.png 图片.png1.1.2 匹配次数
用在要指定次数的字符后面, 用于指定前面的字符要出现的次数
* 匹配前面的字符任意次, 包括0次; 贪婪模式: 尽可能长的匹配, 如: a* 表示任意次
.* 匹配任意长度的任意字符
\? 匹配其前面的字符0或1次
\+ 匹配前面的字符, 至少1次, 即肯定有, >=1
\{\n} 匹配前面的字符n次, 如: a\{10\}
\{m,n\} 匹配前面的字符至少m次, 至多n次
\{,n\} 匹配前面的字符,至多n次, <=n
\{n,\}\ 匹配前面的字符至少n次
图片.png
图片.png
grep的匹配是连续的, 这里只会匹配第三行, 因为匹配的模式是a连续出现3次, 前两行不符合要求, 第三行, 第一组aaa符合, 因为a连续出现3次, 第三组只匹配前三个a, 因为前三个a是连续出现的, 而第四个a是单独的, 后续没有多余的a
图片.png1.1.3 位置锚定
位置锚定可以用于定位出现的位置
^ 行首锚定, 用于模式的最左侧, 如: ^rc, 表示以rc开头的行; ^#表示以#开头的行
$ 行尾锚定, 用于模式的最右侧
^PATTERN$ 用于模式匹配整行
^$ 空行
^[[:space:]]*$ 空白行, 也就是都是空格, 或者写成^ *$
\< 或 \b 词首锚定, 用于单词模式的左侧, 匹配以指定字符串开始的单词
\> 或 \b 词尾锚定, 用于单词模式的右侧, 匹配以指定字符串结尾的单词
\<PATTERN\> 匹配整个单词
#注意: 数字, 字母. 下划线,算作单词内部的内容, 除此之外都不算. 过滤单词时要注意
举例1: 排除掉空行和#开头的行
grep -v '^$' FILE | grep -v '^#'
grep -Ev '^$|^#' /etc/fstab
-
词首锚定
-
词尾锚定
- 匹配整个单词, 和grep -w一样
1.1.4 分组其他
1.1.4.1 分组
分组: 用()将多个字符捆绑在一起, 当做一个整体处理, 如: (root)+表示root作为一个整体出现了至少一次以上
图片.png后向引用: 分组括号中的模式匹配到的内容, 会被正则表达式引擎记录于内部的变量中, 这些变量的命名方式为: \1, \2, \3...
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符. 常用于搜索替换
vim支持基本的正则表达式, 可以利用基本正则表达式在末行模式做查找和替换
- g表示一行如果有多个匹配, 那么都替换
示例:
\(string1\(string2\)\)
\1: string1\(string2\)
\2: string2
注意: 后向引用引用的是前面的分组括号中的模式所匹配的字符, 而非模式本身
搜索替换时, 分组内匹配到的字符和保存匹配到的字符的变量\1, \2, \3...是一一对应的
比如: r..t可以匹配到下面所有的字符串, 如果将r..t设定为分组(r..t)后向引用,做替换时, \1 代表的就是root, r12t, r34t, rXXt; 如果替换后的模式为abc\1, 那么替换后的数据为abcroot, abcr12t, abcr34t, abcrXXt
root
r12t
r34t
rXXt
总结: 利用分组, 后向引用前项做查找替换时, 分组变量\1,\2,...会记录前面对应每个分组中的表达式所能匹配到的文本中的内容, 替换时, 根据新指定的模式, 将\1, \2中存放的内容, 写到\1, \2所在的位置, 源目一一对应
注意: 分组匹配是连续的
图片.png1.1.4.2 或者
或者: ''\|''
案例:
a\|b #a或者b
c\|cat #c或者cat
\(c\|C\)at #cat或者Cat #注意\|或者的优先级较低, 如果有冲突时, 需要把或者的部分用小括号括起来
图片.png
举例: 排除空行和#开头的行
grep -v '^$\|^#' FILE
grep '^[^#]'
grep -v '^\(#\|$\)'
图片.png
1.2 扩展正则表达式
1.2.1 字符匹配元字符
. 任意单个字符
[wang] 指定范围的字符
[^wang] 不在指定范围的字符
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] 小写字母,示例:[[:lower:]],相当于[a-z][:upper:] 大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:digit:] 十进制数字
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
1.2.2 字符匹配
* 匹配前面字符任意次
? 0或1次
+ 1次或多次
{n} 匹配n次
{m,n} 至少m,至多n次
1.2.3 位置锚定
^ 行首
$ 行尾
\<, \b 语首
\>, \b 语尾
1.2.4 分组其它
() 分组
后向引用:\1, \2, ...
| 或者a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat
2 文本处理三剑客 - grep
- grep命令主要对文本的(正则表达式)行基于模式进行过滤
- stream editor, 文本编辑工具
- awk: Linux上的实现gawk, 文本报告生成器
2.1 文本处理三剑客之grep
作用: 文本搜索工具, 根据用户指定的'模式'对目标文本逐行进行匹配检查;打印匹配的行, 也就是包含指定模式字符串的行
模式: 由正则表达式字符及文本字符所编写的过滤条件
格式:
grep [OPTIONS] PATTERN [FILE...]
常见选项:
--color=auto 对匹配到的文本着色显示, 默认选项
-m # 匹配#次后停止, 也就是只显示包含指定模式的前几个匹配的行
-v 显示不被pattern匹配到的行
-i 忽略字符大小写
-n 显示匹配的行号
-c 统计匹配的行数
-o 仅显示匹配到的字符串, 也就是符合模式的内容
-A # after, 后#行, 包含匹配模式的行的后#行
-B # before, 前#行,包含匹配模式的行的前#行
-C # context, 前后各#行,包含匹配模式的行的前后各#行
-e 实现多个选项间的逻辑或关系, 如: grep -e 'cat' -e 'dog' FILE
-w 匹配整个单词
-E 使用扩展正则表达式是, 相当于egrep
-F 不支持正则表达式, 相当于fgrep
-f file 根据模式文件处理
-r 递归目录, 但不处理软连接
-R, 递归目录, 但处理软连接
举例1: 取出本机ip地址
[00:24:55 root@centos8-3 ~]#ifconfig | grep 'broadcast' | tr -s ' ' | cut -d ' ' -f 3
10.0.0.83
举例2: -A, -B, -C, -n 参数
图片.png 图片.png 图片.png 图片.png 图片.png举例3: -e选项, 匹配多个模式, 或关系
选出包含root或者包含bash的行
图片.png举例4: grep实现并且关系过滤, 分次利用管道
选出即包含root也包含bash的行
图片.png举例5: -f file, 利用文件,给grep传匹配模式
效果和-e一样, 都是或关系, 文件中的每一行的字符, 就是匹配模式
图片.png举例6: 利用正则表达式, 取出ifconfig中包含ip地址的行
图片.png[00:54:25 root@centos8-3 ~]#ifconfig | grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}'
inet 10.0.0.83 netmask 255.255.255.0 broadcast 10.0.0.255
inet 127.0.0.1 netmask 255.0.0.0
[01:14:52 root@centos8-3 ~]#ifconfig | grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}'
inet 10.0.0.83 netmask 255.255.255.0 broadcast 10.0.0.255
inet 127.0.0.1 netmask 255.0.0.0
[01:18:30 root@centos8-3 ~]#ifconfig | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | head -1
10.0.0.83
举例7: grep -w, 匹配整个单词, 也就是必须单词以单独的整体出现, 而不能仅仅是某行包含某个单词
图片.png举例8: grep -R 和 grep -r, 递归匹配目录
-r 递归目录, 但不处理软连接
-R, 递归目录, 但处理软连接
可以利用-r或者-R来搜索某个目录下, 包含指定匹配模式的所有文件和路径
图片.png
举例9: grep过滤空白行和有空格组成的行
- '^$': 只是空行
- '^ *$': 既包含空行, 也包含由空格组成的行
[01:36:27 root@centos8-3 /data/prac]#cat -An fstab
1 $
2 $
3 $
4 $
5 $
6 #aaa$
7 #bbb$
8 #ccc$
9 #$
10 # /etc/fstab$
11 # Created by anaconda on Wed Aug 12 13:58:49 2020$
12 #$
13 # Accessible filesystems, by reference, are maintained under '/dev/disk/'.$
14 # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.$
15 #$
16 # After editing this file, run 'systemctl daemon-reload' to update systemd$
17 # units generated from this file.$
18 #$
19 UUID=fd006b07-1a14-47a4-b4bf-5f082a16d02b / xfs defaults 0 0$
20 UUID=761c06b7-40ff-476d-825c-07240b17c4c4 /boot ext4 defaults 1 2$
21 UUID=d637b295-f8f8-4945-a56b-8e47308de873 /data xfs defaults 0 0$
22 UUID=5c6adb82-4c35-43f5-a49a-1523e2c44fe9 swap swap defaults 0 0$
[01:36:17 root@centos8-3 /data/prac]#grep -n '^ *$' fstab
1:
2:
3:
4:
5:
[01:36:21 root@centos8-3 /data/prac]#grep -n '^$' fstab
1:
2:
图片.png
举例10: 过滤掉文本中的, 空行, 都是空格的行, #号开头的注释行, 空格+#号的注释行
[01:40:42 root@centos8-3 /data/prac]#cat fstab
#aaa
#bbb
#ccc
#
# /etc/fstab
# Created by anaconda on Wed Aug 12 13:58:49 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk/'.
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info.
#
# After editing this file, run 'systemctl daemon-reload' to update systemd
# units generated from this file.
#
UUID=fd006b07-1a14-47a4-b4bf-5f082a16d02b / xfs defaults 0 0
UUID=761c06b7-40ff-476d-825c-07240b17c4c4 /boot ext4 defaults 1 2
UUID=d637b295-f8f8-4945-a56b-8e47308de873 /data xfs defaults 0 0
UUID=5c6adb82-4c35-43f5-a49a-1523e2c44fe9 swap swap defaults 0 0
[01:40:44 root@centos8-3 /data/prac]#grep -v '^ *$' fstab | grep -v '^ *#'
UUID=fd006b07-1a14-47a4-b4bf-5f082a16d02b / xfs defaults 0 0
UUID=761c06b7-40ff-476d-825c-07240b17c4c4 /boot ext4 defaults 1 2
UUID=d637b295-f8f8-4945-a56b-8e47308de873 /data xfs defaults 0 0
UUID=5c6adb82-4c35-43f5-a49a-1523e2c44fe9 swap swap defaults 0 0
举例11: 过滤掉,httpd配置文件中注释行
[01:43:55 root@centos8-3 /data/prac]#grep -v '^ *#' /etc/httpd/conf/httpd.conf
举例12: grep -o, 仅显示匹配到的字符串
图片.png举例13: 统计匹配的行数
举例14: 求所有人的年龄之和
图片.png 图片.png