Linux 正则表达式

文本处理工具之grep、egrep、fgrep
  grep:(global search regular expression(RE) and print out the line)
正则表达式分为两类:基本正则表达式BRE和扩展正则表达式ERE
作用:文本搜索工具,根据用户指定的文本模式对目标文件进行逐行搜索匹配,并显示匹配的行(文本过滤工具)
模式:由正则表达式元字符及文本字符所编写的过滤条件
  元字符:类似通配符,不表示字符本身的意义,用于额外功能性的描述

使用格式:默认只支持基本正则表达式,要匹配额外功能的字符用-E
 grep [OPTIONS] 'PATTERN' [File]
  --color 指定颜色--color=auto模式匹配出来的字符串加颜色显示
  -v 反向匹配,显示不能被模式匹配到的行
  -o 仅匹配被模式匹配到的字串,而非整行
  -i 不区分大小写(ignore-case)
  -E 支持扩展正则表达式
  -A # 显示被模式匹配到的行和下一行(#指定要显示的行数)
  -B # 显示被模式匹配到的行和上一行
  -C # 显示被模式匹配到的行和上下各一行
  -q 静默模式,不输出任何信息,只关心是否匹配到,查看echo $?来判断是否匹配到
  -n 显示匹配到模式的行号
  -c 统计匹配到模式的行数
  -e 实现多个匹配模式间的逻辑or关系
  -w 整行匹配整个单词,其匹配到的必须是一个完整的单词,而不是其中一部分
演示:
1、--color=auto 选项,对匹配到的文本着色后高亮显示(CentOS7定义了别名,CentOS6需要自行定义)

2、-i 选项,忽略字符大小写
# 没有匹配到指定的模式
[root@centos7 ~]# grep "ROOT" /etc/passwd
[root@centos7 ~]# grep -i "ROOT" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

3、-o选项,仅显示匹配到的字符串
# 不加 -o 选项,显示的是匹配到的整个行
[root@centos7 ~]# grep "UUID" /etc/fstab
UUID=7bdf8e89-59c8-425e-a108-5c7c115e0afe / xfs defaults 0 0
UUID=3360e49a-d492-4f98-9957-edcb4db93384 /boot xfs defaults 0 0
UUID=eb3cdf15-b9e4-4ea6-b28b-75d4b4a54df8 /usr xfs defaults 0 0
UUID=18deb1ed-ee42-4269-94f3-6791304344e8 swap swap defaults 0 0
# 加上 -o 选项后只显示匹配到的字符串
[root@centos7 ~]# grep -o "UUID" /etc/fstab
UUID
UUID
UUID
UUID

4、-v选项,显示不能够被pattern匹配到的行;
[root@centos7 ~]# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Sun Nov 6 10:30:14 2016
#
# 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
#
UUID=7bdf8e89-59c8-425e-a108-5c7c115e0afe / xfs defaults 0 0
UUID=3360e49a-d492-4f98-9957-edcb4db93384 /boot xfs defaults 0 0
UUID=eb3cdf15-b9e4-4ea6-b28b-75d4b4a54df8 /usr xfs defaults 0 0
UUID=18deb1ed-ee42-4269-94f3-6791304344e8 swap swap defaults 0 0
# 添加-v选项后, 显示不能够被pattern匹配到的行
[root@centos7 ~]# grep -v "UUID" /etc/fstab

#
# /etc/fstab
# Created by anaconda on Sun Nov 6 10:30:14 2016
#
# 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
#

5、-q选项,静默模式不输出任何信息,通常配合 echo $? 使用(为0即匹配到,不为0即没有匹配到)
[root@centos7 ~]# grep -q "UUID" /etc/fstab
[root@centos7 ~]# echo $?
0 # 匹配到
[root@centos7 ~]# grep -q "UUIID" /etc/fstab
[root@centos7 ~]# echo $?
1 # 没有匹配到

6、-n显示匹配到的行号
[root@centos7 ~]# grep -n "root" /etc/passwd
1:root:x:0:0:root:/root:/bin/bash
10:operator:x:11:0:operator:/root:/sbin/nologin
[root@centos7 ~]# grep -n "UUID" /etc/fstab
9:UUID=7bdf8e89-59c8-425e-a108-5c7c115e0afe / xfs defaults 0 0
10:UUID=3360e49a-d492-4f98-9957-edcb4db93384 /boot xfs defaults 0 0
11:UUID=eb3cdf15-b9e4-4ea6-b28b-75d4b4a54df8 /usr xfs defaults 0 0
12:UUID=18deb1ed-ee42-4269-94f3-6791304344e8 swap swap defaults 0 0

7、-c统计匹配的行数
# -c选项,显示匹配到模式的行数
[root@centos7 ~]# grep -c "root" /etc/passwd
2

# 配合-v选项,显示没有匹配到的行数
[root@centos7 ~]# grep -cv "root" /etc/passwd
44

# 显示文件的行数
[root@centos7 ~]# wc -l /etc/passwd
46 /etc/passwd

8、-A #、-B #、-C# 显示匹配到模式的上下文,如下:
# 显示匹配到模式的后3行
[root@centos7 ~]# grep -A 3 "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
--
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin

# 显示匹配到模式的前2行
[root@centos7 ~]# grep -B 2 "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
--
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin

# 显示匹配到模式的前后各2行
[root@centos7 ~]# grep -C 2 "root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
--
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin

9、-e实现多个选项间的逻辑or关系
# 实现的是逻辑或的关系
[root@centos7 ~]# grep -e "root" -e "bash" /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
mageedu:x:1000:1000:mageedu:/home/mageedu:/bin/bash
centos:x:1001:1001:centos,110101,110110,11223:/home/centos:/bin/bash
arclinux:x:1002:1002::/home/arclinux:/bin/bash
# 注意和如下方式的区别(实现的是逻辑与)
[root@centos7 ~]# grep -e "root" /etc/passwd |grep "bash"
root:x:0:0:root:/root:/bin/bash

10、-w整行匹配整个单词

  基本正则表达式的元字符:
  .          任意单个字符
  [ ]         指定范围内的任意单个字符
  [0-9]、[[:digit:]] 所有数字
  [a-z]、[[:lower:]] 所有小写字母    
  [A-Z]、[[:upper:]]  所有大写字母
  [[:alpha:]]     所有的字母
  [[:alnum:]]     所有字母和数字
  [[:space:]]     空格
  [[:putct:]]     所有标点符号
  [^]         指定范围外的任意单个字符

演示:
1、"."匹配任意单个字符

2、[ ]匹配指定范围内的任意单个字符

3、[^]匹配指定范围外的任意单个字符

  次数匹配:用来指定匹配其前面的字符的次数
  *    任意次;例子x*y可以匹配xxy、xy、y
  .*    匹配任意长度的任意字符
  \?    前面字符出现0次或者1次的
  \{m\}  匹配m次
  \{m,n\}  至少m次,至多n次
  \{m,\}  至少m次
  \{0,n}  至多n次
 注意:
  模式中要使用变量替换时需要对模式使用双引号" "
  grep默认工作在贪婪模式:尽可能的长的去匹配字符

演示:

  位置锚定:用于指定字符出现的位置
  ^  锚定行首 ^字符
  $ 锚定行尾 字符$
  ^$ 空白行
  ^PATTERN$  用于模式匹配整行
  ^[[:space:]]*$ 空白行,包含有空格字符的行

  单词的位置锚定
  \< 锚定词首 \<字符 也可以用 \b字符
  \> 锚定词尾 字符\> 也可以用 字符\b
  精确匹配某个单词 \<字符\>
演示:
1、行首,行尾,及模式匹配整行

2、^$空行,不包含有空格字符的行

3、^[[:space:]]*$空白行,包含有空格字符的行

4、单词锚定(词首、词尾、整个单词)

  分组:
  \(\)
  例子:\(ab\)*xy    配置ab同时出现任意次
 分组引用:
  \1 后向引用,引用前面的第一个左括号以及与之对应的右括号中的模式匹配到的内容;前面模式匹配到的结果在\1处又出现一次
  \2 后向引用,引用前面的第二个左括号以及与之对应的右括号中的模式匹配到的内容,\3依次类推
  注意:分组引用是前面模式匹配到的详细内容在后面出现相同的内容的引用,并不是引用前面的匹配模式

演示:

练习题:
1、显示/proc/meminfo文件中以大小s开头的行
[root@centos7 ~]# grep "^[Ss]" /proc/meminfo
SwapCached: 0 kB
SwapTotal: 2098172 kB
SwapFree: 2098172 kB
Shmem: 6872 kB
Slab: 69120 kB
SReclaimable: 42544 kB
SUnreclaim: 26576 kB

# -i 选项忽略大小写
[root@centos7 ~]# grep -i "^s" /proc/meminfo
SwapCached: 0 kB
SwapTotal: 2098172 kB
SwapFree: 2098172 kB
Shmem: 6872 kB
Slab: 69120 kB
SReclaimable: 42544 kB
SUnreclaim: 26576 kB

# 使用扩展的正则表达式
[root@centos7 ~]# grep -E "^(S|s)" /proc/meminfo
SwapCached: 0 kB
SwapTotal: 2098172 kB
SwapFree: 2098172 kB
Shmem: 6872 kB
Slab: 69256 kB
SReclaimable: 42632 kB
SUnreclaim: 26624 kB

2、显示/etc/passwd文件中不以/bin/bash结尾的行
[root@centos7 ~]# grep -v "/bin/bash$" /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:997:995:User for polkitd:/:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
colord:x:996:994:User for colord:/var/lib/colord:/sbin/nologin

3、显示用户rpc默认的shell程序
# 法一:
[root@centos7 ~]# getent passwd rpc
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
[root@centos7 ~]# getent passwd rpc |cut -d: -f7
/sbin/nologin
# 法二:注意一定要锚定词尾
[root@centos7 ~]# grep "^rpc\>" /etc/passwd
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
[root@centos7 ~]# grep "^\<rpc\>" /etc/passwd |cut -d: -f7
/sbin/nologin
# 法三:
[root@centos7 ~]# grep -w "rpc" /etc/passwd
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
[root@centos7 ~]# grep -w "rpc" /etc/passwd |cut -d: -f7
/sbin/nologin

4、找出/etc/passwd中的两位或三位数
[root@centos7 ~]# grep "\<[0-9]\{2,3\}\>" /etc/passwd
# 或者
[root@centos7 ~]# grep -E "\<[0-9]{2,3}\>" /etc/passwd
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
systemd-bus-proxy:x:999:997:systemd Bus Proxy:/:/sbin/nologin
systemd-network:x:998:996:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:997:995:User for polkitd:/:/sbin/nologin
abrt:x:173:173::/etc/abrt:/sbin/nologin
colord:x:996:994:User for colord:/var/lib/colord:/sbin/nologin
libstoragemgmt:x:995:992:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
setroubleshoot:x:994:991::/var/lib/setroubleshoot:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
chrony:x:993:990::/var/lib/chrony:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
geoclue:x:992:989:User for geoclue:/var/lib/geoclue:/sbin/nologin

5、显示/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面存非空白字符的行

6、找出"netstat -tan"命令的结果中以'LISTEN'后跟任意空白字符结尾的行

7、添加用户bash、testbash、basher以及nologin(其shell为/sbin/nologin),而后找出/etc/passwd文件中用户名同shell名的行

 

扩展正则表达式egrep
  使用扩展正则表达式来构建模式,相当于 grep -E;常用选项与grep相同

元字符:
  .          任意单个字符
  [ ]         指定范围内的任意单个字符
  [0-9]、[[:digit:]] 所有数字
  [a-z]、[[:lower:]] 所有小写字母    
  [A-Z]、[[:upper:]] 所有大写字母
  [[:alpha:]]     所有的字母
  [[:alnum:]]     所有字母和数字
  [[:space:]]     空格
  [[:putct:]]     所有标点符号
  [^]         指定范围外的任意单个字符   

次数匹配
  *   匹配其前面的字符任意次
  ?   匹配其前面的字符0或1次
  +   匹配其前面字符至少一次
  {m}  匹配其前面字符m次
  {m,n}  至少m次,至多n次
  {m,}  至少m次
  {0,n} 至多n次

 位置锚定:用于指定字符出现的位置
  ^  锚定行首 ^字符
  $  锚定行尾 字符$
  ^$ 空白行

  单词的位置锚定
  \< 锚定词首 \<字符 也可以用 \b字符
  \> 锚定词尾 字符\> 也可以用 字符\b
  精确匹配某个单词 \<字符\>

  分组:
  ( ) 分组
  |  或者,ac|bc指的是ac或者bc,如果是a(c|b)c指的是acc或abc

练习题:
1、显示当前系统root、mage或centos用户的UID和默认shell
# 采用扩展的正则表达式,或者的关系
[root@centos7 ~]# grep -E "^(root|mage|centos)\>" /etc/passwd
root:x:0:0:root:/root:/bin/bash
centos:x:1001:1001:centos,110101,110110,11223:/home/centos:/bin/bash
mage:x:1003:1004::/home/mage:/bin/bash

# 按关键字取出后,再使用cut命令切割
[root@centos7 ~]# grep -E "^(root|mage|centos)\>" /etc/passwd |cut -d: -f3,7
0:/bin/bash
1001:/bin/bash
1003:/bin/bash

2、找出/etc/rc.d/init.d/functions文件中行首为某单词(包括下划线)后面跟一个小括号的行
# 字母或者下划线至少应该匹配1次,所以有“+”,注意这里的括号要使用转义符“\”
[root@centos7 ~]# grep -E "^[[:alnum:]_]+\(\)" /etc/rc.d/init.d/functions
checkpid() {
__pids_var_run() {
__pids_pidof() {
daemon() {
killproc() {
pidfileofproc() {
pidofproc() {
status() {
echo_success() {
echo_failure() {
echo_passed() {
echo_warning() {
update_boot_stage() {
success() {
failure() {
passed() {
warning() {
action() {
strstr() {
is_ignored_file() {
is_true() {
is_false() {
apply_sysctl() {

[root@centos7 ~]# grep -E -o "^[[:alnum:]_]+\(\)" /etc/rc.d/init.d/functions
checkpid()
__pids_var_run()
__pids_pidof()
daemon()
killproc()
pidfileofproc()
pidofproc()
status()
echo_success()
echo_failure()
echo_passed()
echo_warning()
update_boot_stage()
success()
failure()
passed()
warning()
action()
strstr()
is_ignored_file()
is_true()
is_false()
apply_sysctl()

3、使用egrep取出/etc/rc.d/init.d/functions中其基名
# 思路:从右向左搜索,取其非"/"的字符,其字符(至少出现一次),后面斜线可有可无(?)并以其结尾
[root@centos7 ~]# echo "/etc/rc.d/init.d/functions" |egrep -o "[^/]+/?$"
functions
[root@centos7 ~]# echo "/etc/rc.d/init.d/functions/" |egrep -o "[^/]+/?$"
functions/

# 使用命令取其基名和路径名
[root@centos7 ~]# basename /etc/rc.d/init.d/functions
functions
[root@centos7 ~]# dirname /etc/rc.d/init.d/functions
/etc/rc.d/init.d

4、使用egrep取出上面路径的路径名
[root@localhost tmp]# echo "/etc/rc.d/init.d/functions" | egrep --color=auto -o "/.*/"
/etc/rc.d/init.d/

5、统计以root身份登录的每个远程主机IP地址的登录次数

6、找出ifconfig命令中的1-255之间的数字
[root@centos7 ~]# ifconfig |grep -E -o "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
192
168
1
113
255
255
255
192
168
1
255
64
29
60
2
4
1
1
73
127
1
255
1
128
8
8

7、找出/etc/passwd中用户名同shell名的行
# 找出以非冒号开头的字符,其至少匹配一次,并锚定词尾,中间为任意长度的任意字符,再后向引用其第一个括号的内容,并以其结尾的行
[root@centos7 ~]# grep -E "^([^:]+\>).*\1$" /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

8、显示ifconfig命令结果中所有IPv4地址
# ([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) 当做一个整体,表示0-255间的数字;
# (([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.) 当做一个分组,这里的点要转义
[root@centos7 ~]# ifconfig |grep -E -o "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
192.168.1.113
255.255.255.0
192.168.1.255
127.0.0.1
255.0.0.0

  fgrep 不解析正则表达式模式,想找什么信息直接跟什么字符串
     当无需用到元字符去编写模式时,使用fgrep性能更好

posted @ 2018-10-25 15:33  luck-luck  阅读(786)  评论(0编辑  收藏  举报