Linux--文本处理三剑客之grep
grep概念解释
grep:文本过滤工具,其作用顾名思义是文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到
的行。而模式则是由正则表达式字符及文本字符所编写的过滤条件。
grep有三种命令形式:grep、egrep(支持拓展正则表达式搜索)、fgrep(不支持正则表达式搜索)。
使用方法介绍
1.grep的使用方法grep
grep 命令选项[options] 条件[pattern] 文件名[filename]
当我们仅需要查看简单一些的文件内容时,可以不使用命令选项,如:
1 [root@localhost(mei) app]# grep root /etc/passwd 2 root:x:0:0:root:/root:/bin/bash 3 operator:x:11:0:operator:/root:/sbin/nologin 4 [root@localhost(mei) app]# grep "$user" /etc/passwd #$USER表示当前用户 5 root:x:0:0:root:/root:/bin/bash 6 bin:x:1:1:bin:/bin:/sbin/nologin 7 daemon:x:2:2:daemon:/sbin:/sbin/nologi
grep命令选项如下:
--color=auto:表示搜索结果中关键字高亮显示,这一般使用别名中设置成默认,好查看结果。
1 [root@localhost(mei) app]# alias 2 alias cp='cp -i' 3 alias egrep='egrep --color=auto' 4 alias fgrep='fgrep --color=auto' 5 alias grep='grep --color=auto'
-v 关键字:结果显示不包含关关键字的行,相当于取反
1 [root@localhost(mei) app]# cat /etc/passwd |grep -v "root" 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
-i 关键字:忽略关键字的大小写,有些时候我们不关注结果大小写区别的时候,会使用到
-o 仅显示匹配到的关键字,不显示同行的其他内容
1 [root@localhost(mei) app]# cat /etc/passwd |grep -o "root" 2 root 3 root 4 root 5 root
-w 关键字:与 –o 不同的是,o只显示关键字,w则是显示整行内容中匹配到的关键字整体
1 [root@localhost(mei) app]# cat /etc/passwd |grep -w "root" 2 root:x:0:0:root:/root:/bin/bash 3 operator:x:11:0:operator:/root:/sbin/nologin
-E :该选项其实就等于egrep,表示使用扩展正则表达式
-F :该选项同等于fgrep,表示不使用正则表达式
-q: 在终端上不输出任何结果,但是可以通过ehco “$?”来查看结果,返回值为0则表示成功。
1 [root@localhost(mei) app]# cat /etc/passwd |grep -q root 2 [root@localhost(mei) app]# echo $? 3 0
-A # :显示关键字行及向下的n行,其中#表示数字,下面同是。
-B # :显示关键字行及向上的n行。
-C # :显示关键字行及向上n行和向下的n行
-e 关键字1 -e 关键字2 …… :表示多个关键字之间是或的关系
-n 显示的结果每行前增加行号
-c 仅显示找出的结果的行数
2.正则表达式
正则表达式分两类: 基本正则表达式:BRE
扩展正则表达式:ERE grep -E, egrep
其中元字符分类:字符匹配、匹配次数、位置锚定、分组
接下来先介绍基本正则表达式,因为拓展正则是基于基本正则,大部分功能相似,随后介绍。
基本正则表达式
(1)字符匹配
.:匹配任意单个字符
[] :匹配指定范围内的任意单个字符
[^] :匹配指定范围外的任意单个字符
[:alnum:] : 字母和数字
[:digit:] 十进制数字,也可用 [0-9]
[:alpha:] :代表任何英文大小写字符,亦即 A-Z, a-z
[:lower:] :小写字母
[:upper:] :大写字母
[:blank:] 空白字符(空格和制表符)
[:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃...)
[:xdigit:]十六进制数字
[:graph:] 可打印的非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
(2)匹配次数:
匹配次数用在要指定次数的字符后面,用于指定前面的字符要出现的次数
* :匹配前面的字符任意次,包括0次,也被称为贪婪模式:尽可能长的匹配
.* :任意长度的任意字符
\?: 匹配其前面的字符0或1次
\+: 匹配其前面的字符至少1次
\{n\} :匹配前面的字符n次
\{m,n\} :匹配前面的字符至少m次,至多n次
\{,n\} :匹配前面的字符至多n次
\{n,\}: 匹配前面的字符至少n次
(3)位置锚定:定位出现的位置
^ :表示行首锚定,用于模式的最左侧
$ :表示行尾锚定,用于模式的最右侧
^PATTERN$ :用于模式匹配整行
^$ :表示空行,即回车空行
^[[:space:]]*$ 空白行 ,由空白字符组成的空行。
\< 或 \b: 词首锚定,用于单词模式的左侧
\> 或 \b :词尾锚定;用于单词模式的右侧
\<PATTERN\>: 匹配整个单词
(4)分组:
\(\): 将一个或多个字符捆绑在一起,当作一个整体进行处理,注意在正则表达式中,()表示分组,<>是匹配,如:\(root\)\+
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为 : \1, \2, \3, ...
\1 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符,多用于后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
\|:或者 比如a\|b: a或b C\|cat: C或cat \(C\|c\)at:Cat或cat
例题:
1.显示/etc/passwd文件中不以/bin/bash结尾的行
1 root@localhost(mei) app]# cat /etc/passwd |grep -v "/bin/bash$" 2 bin:x:1:1:bin:/bin:/sbin/nologin 3 daemon:x:2:2:daemon:/sbin:/sbin/nologin 4 adm:x:3:4:adm:/var/adm:/sbin/nologin
2.找出“netstat -tan”命令的结果中以‘LISTEN’后跟任意多个空白字符结尾的行
1 [root@localhost(mei) app]# netstat -tan|grep 'LISTEN[[:space:]]*$' 2 tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 3 tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN
3.显示CentOS7上所有系统用户的用户名和UID
1 [root@localhost(mei) app]# cat /etc/passwd |cut -d':' -f1,3 |grep "\<[0-9]\{1,3\}\>" 2 root:0 3 bin:1 4 daemon:2
4.显示三个用户root、alice、mmmm的UID和默认shell
[root@mmmm(mmm) Packages]# cat /etc/passwd|cut -d: -f1,3,7|grep -w -e root -e alice -e mmmm
root:0:/bin/bash
mmmm:500:/bin/bash
alice:501:/bin/bash
5.统计last命令中以root登录的每个主机IP地址登录次数
1 [root@mmmm(mmm) Packages]#last |grep root |grep '\([0-9]\{1,3\}.\)\{3\}[0-9]\{1,3\}' -o |sort | uniq -c 2 40 172.18.254.247 3 1 172.18.254.96
拓展正则表达式
拓展正则大部分都与基本正则相似,不同的有两处,第一便是部分选项的 ’ \ ‘可以省略,比如 \+ 可以直接表示为+,或 \| 可以直接表示为 |,另一点便是 \不可去掉的选项,只有三个:词首 \< 、 \b,词尾 >\、b\,以及后向引用\1。
使用拓展正则: egrep = grep -E
接下来展示几道例题,便于理解。
1.找出/etc/passwd中的两位或三位数
1 [root@localhost(mei) app]# cat /etc/passwd|egrep "\b[0-9]{2,3}\b" #词首词尾锚定后对[0-9]进行2-3次匹配 2 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin 3 operator:x:11:0:operator:/root:/sbin/nologin 4 games:x:12:100:games:/usr/games:/sbin/nologin 5 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
2.使用egrep取出/etc/rc.d/init.d/functions中其基名
1 [root@localhost(mei) app]# echo /etc/rc.d/init.d/functions/ |egrep -o "[^/]+/?$" 2 functions/
虽然1正则表达式看起来不是很难,理解起来也不困难,可总是不知道为什么实际运用起来的时候就会产生一些错误,这就需要我们在使用时,有个清晰的思路,有些时候我们需要学会反向思维,因为有些过滤条件是很复杂的,但是反过来也许就会简单一些。
但总之一句话,多练才能熟练运用。