系统极客一直在努力
专注操作系统及软件使用技能

如何使用 grep 命令在 Linux 中搜索文件

grep 命令

grep 命令全名 global regular expression print(全局正则表达式打印),是 Linux 系统中最强大和最常用的命令之一。grep 可以搜索一个或多个(输入)文件,以查找与「给定模式」相匹配的行,并将每个匹配行写入标准输出。如果没有指定文件,grep 也可以将其它命令的输出作为标准输入进行读取。

下面系统极客就为大家介绍如何在 Linux 系统中使用 grep 命令进行搜索。

grep 命令语法

在讨论如何使用 grep 命令之前,让我们先回顾一下基本语法:

grep [OPTIONS] PATTERN [FILE...]

方括号中的项目是可选的。

  • OPTIONS 提供 grep 控制其行为的 0 个或多个选项
  • PATTERN 搜索模式
  • FILE 0 个或多个输入文件(名)

使用 grep 在文件中搜索字符串

grep 命令最基本的用法就是在文件中搜索字符串(文本),例如要查看 /etc/passwd 文件中包含 zsh 的行,可以使用如下命令:

grep zsh /etc/passwd

grep 在文件中搜索字符串

如果要搜索的字符串包含空格,则需要将其用单引号双引号括起来,例如:

grep "systemd Network Management" /etc/passwd

grep 在文件中搜索字符串

grep 反向匹配(排除)

如果要显示与搜索模式不匹配的行,可以使用 -v–invert-match 参数。例如,要查看 /etc/passwd 文件中不包含 nologin 的行,可以使用以下命令:

grep -v nologin /etc/passwd

grep 反向匹配

grep 搜索另一命令的输出

如果不是搜索文件,也可以将其它命令的输出结果传递给 grep 作为其搜索的「输入」。例如,要查找当前 Linux 中以 www-data 用户运行的进程,可以执行如下命令:

ps -ef | grep www-data

grep 搜索另一命令的输出

您还可以在命令中链接多个管道。从上图的输出中可以看到,有一行还包含了 grep 进程,如果不想显示该行,则可以将输出再次传递给另一个 grep 实例,例如:

grep 搜索另一命令的输出

grep 递归搜索

要使用递归搜索模式,请加上 -r–recursive 参数,加上此参数后会搜索指定目录中的所有文件,遇到「符号链接」时会跳过。如果要搜索「符号链接」,需使用 -R–dereference-recursive 参数。

在下面的示例中,我们会递归搜索 /etc 目录中所有包含 sysgeek.cn 的字符串:

grep -r sysgeek.cn /etc

该命令将输出包含字符串的行,并在前面显示其文件名。

grep 递归搜索

仅查看文件名

要禁止 grep 的默认输出,并仅显示包含「匹配模式」的文件名,可以使用 -l–files-with-matches 参数。例如,要搜索当前目录中所有以 .conf 结尾并包含 sysgeek.cn字符串的文件,可以执行:

grep -l sysgeek.cn *.conf

grep 仅查看文件名

-l 参数通常会与递归参数 -R 结合使用,例如:

grep -Rl sysgeek.cn /tmp

配置 grep 不区分大小写

默认情况下,grep 是区分大小写的,也就是说大写和小写字符被视为不同。若要在搜索时忽略大小写,可以使用 -i–ignore-case 参数。

grep 完全匹配

当用 grep 搜索 gnu 时,会自动匹配整个单词,如 cygnusmagnum

grep gnu demo.txt

grep 完全匹配

如果要完全匹配搜索的单词字符,可以加上 -w–word-regexp 参数。

单词字符包括:字母、数字(a-zA-Z0-9)和下划线(_)。 其它所有字符都被视为非单词字符。

如果加上 -w 参数执行上述 grep 命令,则仅返回 gnu 作为单独单词的那些行:

grep -w gnu demo.txt

grep 完全匹配

配置 grep 显示行号

要显示搜索字符串所在文本的行数时,可以使用 -n–line-number 参数,加上该参数后,grep 会将匹配内容打印到标准输出,并添加所在文本行号为前缀。

例如要查看 /etc/services 文件中 5222的所在行数,可以执行:

grep -n 5222 /etc/services

可以看到有 351352 这两行:

grep 显示行号

使用 grep 计数

若要对匹配的行进行计数,可以使用 -c–count 参数,例如要查看当前 Linux 中使用 ZSH 的账户数,可以使用如下命令:

grep -c '/usr/bin/zsh' /etc/passwd

grep 计数

grep 多个字符串(模式)

OR 运算符 | 可以连接两个或多个搜索模式。但默认情况下,grep 会将「模式」解释为基本正则表达式,其中「元字符」如 | 会失去其特殊意义,所以必需取反。

如下面的示例中,我们可以在 nginx 错误日志文件中搜索所有 fatalerror 和 critical 单词:

grep 'fatal\|error\|critical' /var/log/nginx/error.loge>

但如果加上扩展正则表达式参数 -E–extended-regexp 参数,则运算符 | 不应取反,如下所示:

grep -E 'fatal|error|critical' /var/log/nginx/error.log

grep 正则表达式

grep 有「基本」和「扩展」两个正则表达式功能集,默认情况下,grep 的模式解释为基本正则表达式,要切换到扩展正则表达式需要加上 -E 参数。

当在「基本」模式下工作时,除「元字符」外的所有其他字符,都与原本的正则表达式相匹配。以下是最常用的「元字符」列表:

  • ^(插入符号)用于匹配开头,例如 ^kangaroo 会匹配以其开头的行:
grep "^kangaroo" demo.txt
  • $(美元符号)用于匹配行尾巴,使用 kangaroo$ 仅在其出现在一行的最后才匹配:
grep "kangaroo$" demo.txt
  • .(句点)用以匹配任意单个字符,例如要匹配以 kan开头,中间有 2 个字符,然后以 roo结尾可以使用以下模式:
grep "kan..roo" demo.txt
  • [](中括号)用以匹配中括号里的任意单个字符,例如要匹配 acceptaccent,可以使用以下模式:
grep "acce[np]t" demo.txt

要屏蔽字符的特殊含义,请使用 \ 反斜杠。

grep 扩展正则表达式

扩展正则表达式包括所有基本元字符,以及其他扩展元字符,用以创建更复杂和强大的搜索模式。例如:

  • 匹配并提取给定文件中的所有电子邮件地址:
grep -E -o "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" demo.txt
  • 匹配并提取给定文件中的所有 IP 地址:
grep -E -o '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' demo.txt

-o 参数用于仅打印匹配的字符串。

打印 grep 匹配行的后 N 行

要打印匹配行后 N 行,请使用 -A–after-context 参数。例如要显示匹配行和后 5 行,可以使用以下命令:

grep -A 5 root /etc/passwd

打印 grep 匹配行的后 N 行

打印 grep 匹配行的前 N 行

要打印匹配行前 N 行,请使用 -B–before-context 参数。例如要显示匹配行和前 3 行,可以使用以下命令:

grep -B 3 www-data /etc/passwd

打印 grep 匹配行的前 N 行

如果您想了解更多信息,可以参考 grep 用户手册

赞(0) 赞赏

评论 1

  1. #1

    几日不见网站终于可以访问了。哈哈。其实可以grep -100可以查看到匹配的前后100行内容

    絮沫纷飞5年前 (2018-11-29)回复

微信赞赏