首页 > 技术文章 > 查找文本工具grep

nufangrensheng 2013-12-07 10:44 原文

许多时候需要从一大堆的命令输出或文本内容中找出一两行关键的内容,例如从系统用户文件中查找某个用户。如果不借助工具,这将是一项非常繁琐的工作,这时可以使用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

推荐阅读