查找文本工具grep
许多时候需要从一大堆的命令输出或文本内容中找出一两行关键的内容,例如从系统用户文件中查找某个用户。如果不借助工具,这将是一项非常繁琐的工作,这时可以使用grep工具对内容进行筛选。
grep(global regular expression print,全局正则表达式打印),来源于最早的行编辑器ed。grep是管理和维护系统时经常用到的一个工具。
一、grep的基本格式
命令格式:
grep [option] pattern [file(file-list)]
grep工具在文件file中查找与字符串pattern匹配的内容,如果找到,则将整行输出到标准输出。
常用选项:
i:忽略大小写。
n:将结果输出的同时,也输出该行的行号。
s:在没有找到匹配的内容时,不显示错误信息。
l:从多个文件中查找时,只输出找到匹配内容的文件名称。
h:从多个文件中查找时,只输出匹配的内容,不显示文件名称。
c:只输出匹配内容的总行数。
v:反转查找,即输出匹配内容以外的行。
grep工作时,总是以行为单位查找。首先将文本的第1行读入缓冲区并执行查找,如果找到匹配的字符串,则输出整行。否则就丢弃缓冲区内容并读入下一个文本行继续查找,直到文本结束。
二、使用grep查找文本
示例文本文件students内容如下:
[root@localhost zhu]# cat students 2821020225 Liulu Sichuan Lixia 01/23/93 89 76 88 72 325 81 2821020115 Liumin Henan lixia 05/14/94 78 65 59 78 280 70 2721020321 Xuli Jiangsu Luolei 12/25/92 76 81 85 79 321 80 2921020632 Xiayu Shanxi Hetao 03/26/93 78 86 92 78 334 84 2721010409 Liwei Sichuan tangwei 11/21/92 98 88 85 85 356 89 2921050313 Heli Xizang Tangwei 07/12/94 56 78 80 45 259 65 2721030227 Wangtao Yunnan Huli 03/21/93 87 76 69 88 320 80
(1)查找关键字
[root@localhost zhu]# grep "92" students 2721020321 Xuli Jiangsu Luolei 12/25/92 76 81 85 79 321 80 2921020632 Xiayu Shanxi Hetao 03/26/93 78 86 92 78 334 84 2721010409 Liwei Sichuan tangwei 11/21/92 98 88 85 85 356 89 2921050313 Heli Xizang Tangwei 07/12/94 56 78 80 45 259 65
(2)显示行号
[root@localhost zhu]# grep -n "92" students 3:2721020321 Xuli Jiangsu Luolei 12/25/92 76 81 85 79 321 80 4:2921020632 Xiayu Shanxi Hetao 03/26/93 78 86 92 78 334 84 5:2721010409 Liwei Sichuan tangwei 11/21/92 98 88 85 85 356 89 6:2921050313 Heli Xizang Tangwei 07/12/94 56 78 80 45 259 65
(3)统计结果
[root@localhost zhu]# grep -c "Xizang" students 1
(4)大小写敏感
[root@localhost zhu]# grep "tangwei" students 2721010409 Liwei Sichuan tangwei 11/21/92 98 88 85 85 356 89
[root@localhost zhu]# grep "Tangwei" students 2921050313 Heli Xizang Tangwei 07/12/94 56 78 80 45 259 65
#使用选项i查找时忽略大小写 [root@localhost zhu]# grep -i "tangwei" students 2721010409 Liwei Sichuan tangwei 11/21/92 98 88 85 85 356 89 2921050313 Heli Xizang Tangwei 07/12/94 56 78 80 45 259 65
(5)反转查找
查询辅导员不是Tangwei和Lixia的学生情况:
[root@localhost zhu]# grep -vi "tangwei" students | grep -vi "lixia" 2721020321 Xuli Jiangsu Luolei 12/25/92 76 81 85 79 321 80 2921020632 Xiayu Shanxi Hetao 03/26/93 78 86 92 78 334 84 2721030227 Wangtao Yunnan Huli 03/21/93 87 76 69 88 320 80
这条命令中的第一个grep先输出不含有Tangwei的所有行,然后通过管道将结果传递给第二个grep命令,第二个命令输出不含有Lixia的所有行。
(6)多文件查找
有时候需要从多个文件中查找一些相关联的内容,这时就要用到多文件查询。例如管理员要从目录/etc的文件中查找有关root用户的内容:
[root@localhost zhu]# grep -l "root" /etc/* /etc/aliases /etc/aliases.db /etc/anacrontab /etc/crontab /etc/gpm-root.conf /etc/group ...
grep输出了目录/etc中所有含有root字符串的文件名。
查询密码文件/etc/passwd和影子文件/etc/shadow中含有字符串root的所有行,并且不显示文件名称:
[root@localhost zhu]# grep -h "root" /etc/passwd /etc/shadow root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin root:$1$t4$eOBy2Gb9IAyS.1WiFU1bU.:16021:0:99999:7:::
(7)在命令输出和变量中查找
grep不仅可以从文件中查询字符串,还可以从字符串和字符串变量中查询:
#使用grep在命令输出中查找 [root@localhost zhu]# echo "Welcome to Beijing" | grep "to Beijing" Welcome to Beijing #使用grep在变量中查找 [root@localhost zhu]# A="Welcome to Beijing" [root@localhost zhu]# echo $A | grep "Beijing" Welcome to Beijing #使用变量保存查找的字符串 [root@localhost zhu]# A="Beijing" [root@localhost zhu]# echo "Welcome to Beijing" | grep "$A" Welcome to Beijing
注意:在使用grep查找时,被查找的字符串可以不使用引号。但在被查找的字符串中有空格或被查询的字符串保存在一个变量中时,应该使用引号以免被grep误解为一个命令或参数。
三、行首、行尾匹配查找
文本的行首、行尾通常用于保存特殊意义的字段,例如产品序号、销售额等内容,因此从行首和行尾匹配查找可能会比较频繁。
1、行首匹配
查询文件students中所有2008年入学的学生:
[root@localhost zhu]# grep '^28' students 2821020225 Liulu Sichuan Lixia 01/23/93 89 76 88 72 325 81 2821020115 Liumin Henan lixia 05/14/94 78 65 59 78 280 70
使用行首匹配显示第5、6个字符为02的所有行:
[root@localhost zhu]# grep '^....02' students 2821020225 Liulu Sichuan Lixia 01/23/93 89 76 88 72 325 81 2821020115 Liumin Henan lixia 05/14/94 78 65 59 78 280 70 2721020321 Xuli Jiangsu Luolei 12/25/92 76 81 85 79 321 80 2921020632 Xiayu Shanxi Hetao 03/26/93 78 86 92 78 334 84
2、行尾匹配
例如查找平均成绩85以上的学生情况:
[root@localhost zhu]# grep -v '[0-7][0-9]$' students | grep -v '8[0-4]$' 2721010409 Liwei Sichuan tangwei 11/21/92 98 88 85 85 356 89
当然也可以配合常用的正则表达式查找。
四、使用或、与多模式匹配查找
(1)或匹配模式
使用参数E让grep命令将要匹配的字符串延伸为一个普通的表达式,此时可以使用“|”表示或匹配模式,即只需要匹配两个字符串中的任意一个即可。
例如查询来自河南和云南学生的详细情况:
[root@localhost zhu]# grep -E 'Henan|Yunnan' students 2821020115 Liumin Henan lixia 05/14/94 78 65 59 78 280 70 2721030227 Wangtao Yunnan Huli 03/21/93 87 76 69 88 320 80
(2)与模式匹配
然而参数E并不支持与匹配模式查询,此时可以使用多条件管道实现。例如要查询名叫Lixia的学生中有哪些来自Sichuan:
[root@localhost zhu]# grep -i "Lixia" students | grep "Sichuan" 2821020225 Liulu Sichuan Lixia 01/23/93 89 76 88 72 325 81
五、grep工具应用实例
1、精简配置文件
在Linux系统中,管理员经常接触到各种类型的服务器配置文件。这些配置文件通常都使用了一个通用的注释格式,即使用井号“#”(通常是注释信息)或“;”(通常标志该行是默认设置)作为开头标志。配置文件中的注释信息和默认配置语句行写得非常详细,这些语句行比真正起作用的配置往往多出数十倍,甚至更多。
通常情况下,熟悉这些配置文件的管理员会使用grep工具的参数v精简这些配置文件,让这些配置文件的可读性更高,更方便修改。此处以精简Samba服务器的配置文件smb.conf为例:
[root@localhost zhu]# cp /etc/samba/smb.conf ./ [root@localhost zhu]# mv smb.conf smb.conf_backup [root@localhost zhu]# cat smb.conf_backup | grep -v '#' | grep -v '^;' | grep -v '^$' >smb.conf
2、从系统管理命令输出中查找
grep工具是Linux中最常用的命令之一,管理员需要经常使用它对命令结果执行筛选,以便查看关键内容。
例如从服务列表中筛选出蓝牙服务,以便于查看这个服务在不同运行级别中的启动状态:
[root@localhost zhu]# chkconfig --list | grep bluetooth bluetooth 0:off 1:off 2:on 3:on 4:on 5:on 6:off