grep是英文词组“global search regular expression and print out the line”的缩写,意思是全局搜索正则表达式,并将结果输出。
通常将grep命令与正则表达式搭配使用,命令选项作为搜索过程中的补充或对输出结果的筛选,命令模式十分灵活,功能非常强大。
如果想要搜索包含某一文本模式的文件,可以使用 grep 命令。通过使用该命令,可以搜索单个文件或者递归搜索整个目录结构。
当搜索时,可以在屏幕上打印输出满足条件的行,也可以仅列出包含搜索词的文件名。
默认情况下,grep 以区分大小写的方式搜索文本,也可以设置不区分大小写。
除了搜索文件外,还可以使用 grep 命令搜索标准输出。即如果某一命令输出了许多文本,现需要从中找到包含特定文本的行,也可使用grep进行过滤。
grep命令的语法格式如下:
grep [选项] 文本模式 文件
常用选项如下:
选项 | 作用或含义 |
-i | 忽略大小写 |
-c | 只输出匹配行的数量 |
-l | 只列出符合匹配的文件名,不列出具体的匹配行 |
-n | 列出所有的匹配行,显示行号 |
-h | 查询多文件时不显示文件名 |
-s | 不显示不存在、没有匹配文本的错误信息 |
-v | 显示不包含匹配文本的所有行 |
-w | 匹配整词 |
-x | 匹配整行 |
-r | 递归搜索 |
-q | 禁止输出任何结果,已退出状态表示搜索是否成功 |
-b | 打印匹配行距文件头部的偏移量,以字节为单位 |
-o | 与-b结合使用,打印匹配的词距文件头部的偏移量,以字节为单位 |
-F | 匹配固定字符串的内容 |
-E | 支持扩展的正则表达式 |
实例演示:
1、在指定文件中搜索某个文本模式,输出包含了该文本模式的行
# 文本模式有空格时,建议用引号括起来,默认区分大小写
[root@myEuler ~]# grep 'desktop' /etc/services
desktop-dna 2763/tcp # Desktop DNA
desktop-dna 2763/udp # Desktop DNA
# 不区分大小写
[root@myEuler ~]# grep -i 'desktop' /etc/services
sco-dtmgr 617/tcp # SCO Desktop Administration Server
sco-dtmgr 617/udp # SCO Desktop Administration Server
……此处省略部分输出……
2、在指定的多个文件中搜索
# 在多个文件中找出以root开头的行
[root@myEuler ~]# grep ^root /etc/passwd /etc/group
/etc/passwd:root:x:0:0:root:/root:/bin/bash
/etc/group:root:x:0:
# 在多个文件中找出以root开头的行,不显示文件名
[root@myEuler ~]# grep -h ^root /etc/passwd /etc/group
root:x:0:0:root:/root:/bin/bash
root:x:0:
# 在多个文件中查找,输出符合条件的行及其行号
[root@myEuler ~]# grep -hn ^nobody /etc/passwd /etc/group
13:nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
24:nobody:x:65534:
3、反向匹配,即找出不包含指定文本模式的行
#输出所有不包含nologin的行
[root@myEuler ~]# grep -v nologin /etc/passwd
root:x:0:0:root:/root:/bin/bash
sync:x:5:0:sync:/sbin:/bin/sync
……此处省略部分输出……
4、整词/整行匹配
#查找整行内容为lang zh_CN.UTF-8的行
[root@myEuler ~]# grep -x 'lang zh_CN.UTF-8' anaconda-ks.cfg
lang zh_CN.UTF-8
#找出文本行中包含单词graphical的行
[root@myEuler ~]# grep -w graphical anaconda-ks.cfg
# Use graphical install
graphical
5、递归搜索,不仅搜索指定目录,还搜索其内子目录内是否有包含指定文本模式的文件
[root@myEuler ~]# grep -lsr 'openEuler 22.03' /etc
/etc/os-release
6、从命令输出信息中查找
grep也可以从命令输出信息中查找特定文本,只是通常需要配合管道线,示例如下:
# 从cat命令的执行结果中查找特定文本graphical
[root@myEuler ~]# cat anaconda-ks.cfg | grep graphical
# Use graphical install
graphical
# 从网络连接中筛查出sshd进程连接
[root@myEuler ~]# netstat -antlp | grep sshd
7、利用正则表达式搜索特定文本模式
正则表达式包括基础正则表达式和扩展正则表达式。前面的以root开头的头(^root)就是一种基础正则表达式。
(1)基础正则表达式
常用的基础正则表达式如下:
正则表达式 | 含义 |
* | *号前面的一个字符重复0到任意多次,如a*表示有0或多个a |
. | 表示此处一定有一个且仅有一个任意字符 |
[] | 与通配符相同,表示方括号中的单个字符,如[0-9]表示单个数字 |
^str | 以str开头的行,如^start表示以start开头的行 |
str$ | 以str结尾的行,如end$表示以end结尾的行 |
^$ | 开头与结尾间无内容,也就是空行 |
[[:alpha:]] | 代表任意字母,包括大小写 |
[[:alnum:]] | 代表任意字母和数字,包括大小写 |
[[:digit:]] | 代表任意数字,即0~9 |
[[:lower:]] | 代表任意小写字母 |
[[:upper:]] | 代表任意大写字母 |
[[:blank:]] | 代表任意空格或制表符Tab |
[[:print:]] | 代表任意可打印的字符 |
[[:punct:]] | 代表标点符号 |
# 打印出所有以小写字母开头的行
[root@myEuler ~]# grep ^[[:lower:]] anaconda-ks.cfg
graphical
keyboard --vckeymap=cn --xlayouts='cn'
……此处省略部分输出……
# 打印出所有非空行
[root@myEuler ~]# grep -v ^$ anaconda-ks.cfg
# Generated by Anaconda 36.16.5
# Generated by pykickstart v3.34
……此处省略部分输出……
(2)扩展正则表达式
正则表达式 | 含义 |
? | ?号前面的一个字符重复0次或1次,如a?表示有0或1个a |
+ | +号前面的一个字符至少重复1次,如a+表示有1个a或多个a |
| | 表示|两侧的字符串是或者的关系,如dog|cat,坚线两侧无空格 |
() | 表示括号内的字符串是一个组,如(c|b)a(b|t)表示cab、cat、bab、bat |
\{n,m\} | 将前面的一个字符重复n到m次,\{n\}表示n次,\{n,\}表示n次以上 |
#查看cron或rsyslog进程状态
[root@myEuler ~]# ps aux | grep -E '(cron|rsyslog)'
root 1831 0.0 0.0 164368 9880 ? Ssl 3月07 0:04 /usr/sbin/rsyslogd -n -i/var/run/rsyslogd.pid
root 1858 0.0 0.0 23240 2736 ? Ss 3月07 0:00 /usr/sbin/crond -n
root 338425 0.0 0.0 21672 1944 pts/0 S+ 09:21 0:00 grep --color=auto -E (cron|rsyslog)
下面再举几个关于扩展正则表达式的例子,以帮助理解。
现假定file1的文件内容如下。
[root@myEuler ~]# cat file1
gg
go
gog
google
gooogle
gooooogle
# 找出包含文本模式go?g的行,其中的字母o至多出现一次
[root@myEuler ~]# grep -E 'go?g' file1
gg
gog
# 找出包含文本模式go+g的行,其中的字母o至少出现一次
[root@myEuler ~]# grep -E 'go+g' file1
gog
google
gooogle
gooooogle
# 找出包含文本模式gog或者ggg的行
[root@myEuler ~]# grep -E 'g(o|g)g' file1
gog
# 找出包含文本模式go{2,5}g的行,其中的字母o可出现2到5次,其中的{}需转义
[root@myEuler ~]# grep -E go\{2,5\}g file1
google
gooogle
gooooogle