grep
字数: 2070 字 时长: 8 分钟
grep
是一个强大的文本搜索工具,用于在文件或文本流中查找符合特定模式(通常是正则表达式)的行,并将这些行输出。grep
的名称源自 Global Regular Expression Print(全局正则表达式打印)的缩写。
grep
的核心功能是在一个或多个文件中搜索指定的字符串模板(模式),并将匹配的行输出到屏幕(标准输出)。grep
可用于 shell 脚本,因为 grep
通过返回一个状态值来说明搜索的状态,如果模板搜索成功,则返回 0
,如果搜索不成功,则返回 1
,如果搜索的文件不存在,则返回 2
。利用这些返回值就可进行一些自动化的文本处理工作。
基本语法
grep
的基本语法如下:
grep [OPTION...] PATTERNS [FILE...]
PATTERNS
:模式,表示要搜索的字符串或正则表达式。FILE
:要搜索的文件(可以是一个或多个文件,如果未指定文件,则从标准输入读取)。
grep
提供了丰富的选项来满足不同的搜索需求。以下是一些常用选项:
搜索控制 | 作用 |
---|---|
-i | 忽略大小写。 |
-v | 反向匹配,显示不包含模式的行。 |
-w | 匹配整个单词。 |
-x | 匹配整行。 |
上下文控制 | 作用 |
---|---|
-A <n> | 显示匹配行及其后 n 行 |
-B <n> | 显示匹配行及其前 n 行。 |
-C <n> | 显示匹配行及其前后各 n 行。 |
输出控制 | 作用 |
---|---|
-n | 显示匹配行的行号。 |
-c | 统计匹配行的数量。 |
-o | 只输出匹配的部分,而不是整行。 |
-q | 静默模式,不输出任何内容,仅通过返回值表示是否匹配成功(常用于脚本中)。 |
-s | 会禁止错误消息的输出。这意味着,如果使用此选项运行 grep ,并且发生错误(例如,文件不存在),则不会在终端中显示错误消息。 |
文件控制 | 作用 |
---|---|
-r 或 -R | 递归搜索目录中的文件。但 -R 会遵循所有符号链接。 |
--include | 指定要搜索的文件类型。 |
--exclude | 排除特定文件类型。 |
grep
支持基本正则表达式(BRE)和扩展正则表达式(ERE)。可以通过 -E
选项启用扩展正则表达式。下是一些常见的正则表达式元字符及其功能:
元字符 | 功能 | 示例 | 示例的匹配对象 |
---|---|---|---|
^ | 行首定位符 | ^love | 匹配所有以 love 开头的行 |
$ | 行尾定位符 | love$ | 匹配所有以 love 结尾的行 |
. | 匹配除换行外的单个字符 | l..e | 匹配包含字符 l、后跟两个任意字符、再跟字母 e 的行 |
* | 匹配零个或多个前导字符 | *love | 匹配在零个或多个空格紧跟着模式 love 的行 |
[] | 匹配指定字符组内任一字符 | [Ll]ove | 匹配包含 love 和 Love 的行 |
[^] | 匹配不在指定字符组内的任一字符 | [^Ll]ove | 匹配不以 L 或 l 开头,但后面跟 ove 的行 |
? | 匹配零个或一个前导字符 | colou?r | 匹配 color 或 colour |
+ | 匹配一个或多个前导字符 | lo+ve | 匹配 love,但不匹配 lve |
{n,m} | 匹配前导字符出现的次数范围 | lo{2,4}ve | 匹配 loove、loooove 等,但不匹配 love 或 loooooove |
| | 逻辑或 | love|like | 匹配 love 或 like |
\ | 转义字符 | \. | 匹配字面意义上的 . ,而不是任意字符 |
() | 分组 | (love|like) you | 匹配 love you 或 like you |
匹配条件
搜索指定文件中包含某个关键词的内容行
在 /etc/passwd 文件中查找包含
root
的行:shell[root@localhost ~]# grep root /etc/passwd root:x:0:0:root:/root:/bin/shell operator:x:11:0:operator:/root:/sbin/nologin
搜索多个文件中包含某个关键词的内容行
在 /etc/passwd 和 /etc/shadow 文件中查找包含
root
的行:shell[root@localhost ~]# grep root /etc/passwd /etc/shadow /etc/passwd:root:x:0:0:root:/root:/bin/shell /etc/passwd:operator:x:11:0:operator:/root:/sbin/nologin /etc/shadow:root:$6$9dGlhMoEUng5lWby$RFSTfWO5GH/Cen49s9.5I7sXkGC5jA0R76e9VDHX.1psMU/biK0olqti/np3vvwkEGq9e0Zu7qQmsnzMoo3p30::0:99999:7:::
忽略大小写搜索
在 /etc/shadow 文件中查找包含
F
或f
的行(忽略大小写):shell[root@localhost ~]# grep -i F /etc/shadow root:$6$9dGlhMoEUng5lWby$RFSTfWO5GH/Cen49s9.5I7sXkGC5jA0R76e9VDHX.1psMU/biK0olqti/np3vvwkEGq9e0Zu7qQmsnzMoo3p30::0:99999:7::: ftp:*:19820:0:99999:7:::
查看匹配行的上下文
在 /etc/passwd 文件中查找包含
ftp
的行,并显示匹配行及其前后各 1 行:shell[root@localhost ~]# grep -1 ftp /etc/passwd games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:65534:65534:Kernel Overflow User:/:/sbin/nologin
取反匹配
在 /etc/passwd 文件中查找不包含
nologin
的行:shell[root@localhost ~]# grep -v nologin /etc/passwd root:x:0:0:root:/root:/bin/shell sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt
显示匹配行的文件名
在 /etc/passwd 和 /etc/shadow 文件中查找包含
root
的行,并显示文件名:shell[root@localhost ~]# grep -H root /etc/passwd /etc/shadow /etc/passwd:root:x:0:0:root:/root:/bin/shell /etc/passwd:operator:x:11:0:operator:/root:/sbin/nologin /etc/shadow:root:$6$9dGlhMoEUng5lWby$RFSTfWO5GH/Cen49s9.5I7sXkGC5jA0R76e9VDHX.1psMU/biK0olqti/np3vvwkEGq9e0Zu7qQmsnzMoo3p30::0:99999:7:::
统计匹配行的数量
统计 /etc/passwd 和 /etc/shadow 文件中包含
root
的行数:shell[root@localhost ~]# grep -c root /etc/passwd /etc/shadow /etc/passwd:2 /etc/shadow:1
递归搜索目录及其子目录
在 /etc/ 目录及其子目录下的所有文件中查找包含
root
的文件名:shell[root@localhost ~]# grep -lr root /etc/ /etc/aliases /etc/anacrontab /etc/audit/auditd.conf /etc/chrony.keys /etc/cron.d/0hourly /etc/crontab ……
注意,如果没有加选项
-r
不会递归搜索子目录,遇到目录的话会提示Is a directory
。
正则匹配
搜索以某个字符串开头的行
在 /etc/selinux/config 文件中查找以
SELINUX
开头的行:shell[root@localhost ~]# grep ^SELINUX /etc/selinux/config SELINUX=enforcing SELINUXTYPE=targeted
搜索以某个字符串结尾的行
在 /etc/selinux/config 文件中查找以
SELINUX
结尾的行:shell[root@localhost ~]# grep SELINUX$ /etc/selinux/config
这里没有找到就没有输出。
同时匹配多个条件
在 /etc/selinux/config 文件中查找包含
enforcing
、permissive
或disabled
的行:shell[root@localhost ~]# grep -E "enforcing|permissive|disabled" /etc/selinux/config # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. # NOTE: Up to RHEL 8 release included, SELINUX=disabled would also # fully disabled instead of SELinux running with no policy loaded, you SELINUX=enforcing
过滤空行和注释行
在 /etc/selinux/config 文件中查找非空行且非注释行(即不以
#
开头且不为空的行):shell[root@localhost ~]# grep -Ev "^#|^$" /etc/selinux/config SELINUX=enforcing SELINUXTYPE=targeted
其他常用组合
显示匹配行的行号
在 /etc/passwd 文件中查找包含
root
的行,并显示行号:shell[root@localhost ~]# grep -n root /etc/passwd 1:root:x:0:0:root:/root:/bin/shell 10:operator:x:11:0:operator:/root:/sbin/nologin
只输出匹配的部分
在 /etc/passwd 文件中查找
root
,并只输出匹配的部分(而不是整行):shell[root@localhost ~]# grep -o root /etc/passwd root root root root
从文件中读取模式
shellerror warning critical
shellThis is an error message. This is a warning message. This is a normal message. This is a critical error.
使用
-f
选项,grep
会逐行读取 patterns.txt 中的模式,并在 file.txt 中查找包含这些模式的行。如果某一行包含 patterns.txt 中的任意一个模式,这一行就会被匹配并输出:shell[root@localhost ~]# grep -f patterns.txt file.txt This is an error message. This is a warning message. This is a critical error.
如果有多个模式需要搜索,手动在命令行中输入这些模式会非常麻烦。将这些模式保存到一个文件中,可以更方便地管理和复用。并且如果搜索模式需要频繁更新,只需修改 patterns.txt 文件,而不需要修改命令。
结合管道使用
从 /var/log/messages 文件中查找包含
error
的行(忽略大小写):shell[root@localhost ~]# cat /var/log/messages | grep -i error …… Jan 15 08:18:43 localhost irqbalance[714]: Cannot change IRQ 73 affinity: Input/output error Jan 15 08:18:43 localhost irqbalance[714]: Cannot change IRQ 63 affinity: Input/output error
高级用法
在 /var/log 目录及其子目录下的所有文件中查找包含 ERROR
的行,但排除 .log
文件:
[root@localhost ~]# grep -r --exclude="*.log" ERROR /var/log
/var/log/anaconda/syslog:08:43:45,471 WARNING org.fedoraproject.Anaconda.Modules.Storage:ERROR:blivet:edd: unable to match edd entry 0x80