文本处理工具之grep
===========================================================================
概述:
===========================================================================
Linux上文本处理三剑客和正则表达式
1.文本处理三剑客
★三剑客:
◆grep,egrep,fgrep:文本过滤(模式:pattern)工具
grep:基本正则表达式; -E,-F
egrep:扩展正则表达式;-G,-F
fgrep(不支持正则表达式搜索);
◆sed:stream editor,流编辑器;文本编辑工具
◆aek:Linux上的实现gawk,文本报告生成器(格式化文本)
2.正则表达式
★正则表达式:REGEXP
★正则表达式分为两类:
◆grep工具支持基本的正则表达式,egrep支持扩展的正则表达式,并且grep的-E 选项起始就是egrep
grep 详解
1.简介
★grep
☉作用:
◆模式:
☉语法格式:
演示:
1.使用grep过滤/etc/passwd 文件中关键字为root的方法:
# 过滤模式为 root
[root@centos7 ~]# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
# 过滤模式为 变量引用
[root@centos7 ~]# grep $USER /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@centos7 ~]# grep '$USER' /etc/passwd # 强引用,变量不替换
[root@centos7 ~]# grep "$USER" /etc/passwd # 弱引用,变量替换
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
# 过滤模式为:命令引用
[root@centos7 ~]# grep `whoami` /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
2.grep命令表达式常用选项
★常用选项:
--color=auto:对匹配到的文本着色后高亮显示;
-i:ignorecase,忽略字符大小写;
-o:仅显示匹配到的字符串;
-v:显示不能够被pattern匹配到的行;
-q:静默模式,即不输出任何信息,只关心匹配的有没有找到,不关心内容,通常配合 echo $? 使用;
-n:显示匹配到模式的行号;
-c:统计匹配到模式的行数;
-A #:after,显示匹配到模式的后#行;
-B #:before,显示匹配到模式的前#行;
-C #:context,显示匹配到模式的前后各#行
-e:实现多个匹配模式间的逻辑or关系
-w:整行匹配整个单词,其匹配到的必须是一个完整的单词,而不是其中一部分;
-E:使用ERE,支持使用扩展的正则表达式,同egrep
注意:
演示:
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:整行匹配整个单词

正则表达式详解
★正则表达式:REGEXP
☉正则表达式分为两类:
☉正则表达式引擎:
☉基本正则表达式元字符分类:
1.字符匹配
★字符:
◆ . :匹配任意单个字符;
◆[ ] :匹配指定范围内的任意单个字符
[:upper:] : 所有大写字母;
[:lower:]:所有小写字母;
[:alpha:]:所有字母(不区分大小写)
[:digit:]:表示所有的数字;
[:alnum:]:表示所有的字母和数字;
[:space:]:表示所有的空白字符;
[:punct:]:表示所有的标点符号
◆[^] :匹配指定范围外的任意单个字符
演示:
1."." 匹配任意单个字符

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

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

2.匹配次数
★匹配次数:
☉表示方法如下:
◆ *:匹配前面的字符任意次;(0次,1次,或多次)
eg: grep "x*y" 则
abxy 可以;
xay可以;
xxy可以;
x不可以;
y可以;
◆ .* :任意长度的任意字符;
◆ \? :匹配其前面的字符0或1次,即前面的可有可无;
◆ \+ :匹配其前面的字符1次或多次,即前面的字符要出现至少1次;
◆ \{m\}:匹配前面的字符m次;(精确匹配)
◆ \{m,n\}:匹配前面的字符至少m次,至多n次;
\{0,n\}:匹配前面的字符至多n次;
\{m,\}:匹配前面的字符至少m次
演示:
1.

2.

3.位置锚定
★位置锚定
☉作用:
☉表示方法如下:
◆ ^:行首锚定,用于模式的最左侧;(表示以什么开头的行)
◆ $:行尾锚定,用于模式的最右侧;(表示以什么结尾的行)
◆ ^PATTERN$:用于模式匹配整行;
◆单词:非特殊字符组成的连续字符(字符串)都成为单词
演示:
1.行首,行尾,及模式匹配整行

2.^$: 空行,不包含有空格的行

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

4.单词锚定(词首,词尾,整个单词)
4.分组及引用
★分组:
◆分组是指将一个或多个字符捆绑在一起,当做一个整体进行处理,其符号为:\(\)
如:\(xy\)*ab 表示,xy这个整体可以出现任意次;
◆分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量为:
示例:
\(ab\+\(xy)*\)
★引用:
演示:

练习:
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和扩展的正则表达式
1.egrep
★egrep
☉语法格式:
☉常用选项:
--color=auto:对匹配到的文本着色后高亮显示;
-i:ignorecase,忽略字符大小写;
-o:仅显示匹配到的字符串;
-v:显示不能够被pattern匹配到的行;
-q:静默模式,即不输出任何信息,只关心匹配的有没有找到,不关心内容,通常配合 echo $? 使用;
-n:显示匹配到模式的行号;
-c:统计匹配到模式的行数;
-A #:after,显示匹配到模式的后#行;
-B #:before,显示匹配到模式的前#行;
-C #:context,显示匹配到模式的前后各#行
-e:实现多个匹配模式间的逻辑or关系
-w:整行匹配整个单词,其匹配到的必须是一个完整的单词,而不是其中一部分;
-G:支持使用基本的正则表达式,同grep
注意:
2.扩展正则表达式
★字符匹配:
◆ . :匹配任意单个字符;
◆[ ] :匹配指定范围内的任意单个字符
[:upper:] : 所有大写字母;
[:lower:]:所有小写字母;
[:alpha:]:所有字母(不区分大小写)
[:digit:]:表示所有的数字;
[:alnum:]:表示所有的字母和数字;
[:space:]:表示所有的空白字符;
[:punct:]:表示所有的标点符号
◆[^] :匹配指定范围外的任意单个字符
★匹配次数:
◆ *:匹配前面的字符任意次;(0次,1次,或多次)
◆ .* :任意长度的任意字符;
◆ ? :匹配其前面的字符0或1次,即前面的可有可无;
◆ + :匹配其前面的字符1次或多次,即前面的字符要出现至少1次;
◆ {m}:匹配前面的字符m次;(精确匹配)
◆ {m,n}:匹配前面的字符至少m次,至多n次;
{0,n}:匹配前面的字符至多n次;
{m,}:匹配前面的字符至少m次
★位置锚定
◆ ^:行首锚定,用于模式的最左侧;(表示以什么开头的行)
◆ $:行尾锚定,用于模式的最右侧;(表示以什么结尾的行)
◆ ^PATTERN$:用于模式匹配整行;
◆单词:非特殊字符组成的连续字符(字符串)都成为单词
★分组及引用:
◆():分组,括号内的模式匹配到的字符会被记录于正则表达式引擎的内部变量中
◆后向引用:\1,\2,\3...
◆或者:
a|b:a或者b;
C|cat:C或者cat;
(c|C)at:cat或者Cat
练习:
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取出上面路径的路径名
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
Ctrl+Enter 发布
发布
取消