如何使用Grep

December 17, 2023
测试
测试
测试
测试
5 分钟阅读

Grep是一个命令行实用程序,可以使用常见的正则表达式语法搜索和过滤文本。它无处不在,动词“to grep”已经成为“搜索”的同义词。它grep是一个有用的工具,用于在选择的文件中查找所有出现的搜索词,过滤日志文件或流,或作为一部分脚本或命令链。

本教程需要一台已经设置好可以使用sudo命令的非root账号的CentOS服务器,并且已开启防火墙。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后在购买服务器。

使用Grep

本指南引用了GNU grep的最新版本,默认情况下所有的腾讯云CVM的镜像中都有包含。它也是几乎所有基于Linux的操作系统发行版中提供的软件包的公共基础选择的一部分。

Grep命令

grep的一个基础用法如下:

grep "string" ~/threads.txt

grep的第一个参数是搜索模式。第二个(可选)参数是要搜索的文件的名称。上面的序列将搜索~/threads.txt文件中出现的所有“string”。

如果要搜索多个文件,-r标志将启用目录树的递归搜索:

grep -r "string" ~/thread/

在特定文件上使用时,grep仅输出包含匹配字符串的行。当以递归模式运行时,grep输出文件的完整路径,后跟冒号以及与模式匹配的行的内容。默认情况下,grep中的模式是基本的正则表达式。如果您需要更具表现力的正则表达式语法,grep能够接受具有以下标志的备用格式的模式:

标志

用法

-E

使用扩展正则表达式语法。相当于已弃用的egrep命令。

-P

使用Perl正则表达式语法。

Grep提供了许多强大的选项来控制其输出:

标志

用法

-o

仅输出每行的匹配段,而不是每个匹配行的完整内容。

-n

打印每个匹配行的行号。

-C 2

除匹配的行外,还显示2个(或其他数量)上下文行。

除了从文件中读取内容外,grep还可以从标准输入中读取和过滤文本。任何命令或流的输出都可以通过管道输出到grep命令。然后,grep根据指定的匹配模式过滤此输出,并仅输出匹配的行。例如,给定以下命令:

ls --help | grep "dired"

这会过滤ls命令帮助文本的输出并查找“dired”,并将它们输出到标准输出:

-D, --dired generate output designed for Emacs' dired mode

正则表达式概述

虽然简单的模式匹配对于某些过滤任务已经足够,但grep真正的强大之处在于它能够使用正则表达式进行复杂的模式匹配。正则表达式中的大多数字符与字面上的输入数据匹配; 但是,有一些序列具有特殊意义:

符号

结果

匹配任何角色。

*

匹配前一个字符的零个或多个实例。

+

匹配前一个字符的一个或多个实例。

[]

匹配括号内的任何字符。

()

创建一个子表达式,可以将其组合以生成更复杂的表达式。

|

OR运算符; (www | ftp)匹配“www”或“ftp”。

^

匹配一行的开头。

$

匹配线的末尾。

\

规避以下角色。由于.匹配任何字符,以匹配您需要使用的文字句点\.。

使用Grep 过滤日志

一个grep流行的用途是从系统日志中提取有用的信息:

grep -Eoc "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.* 200"  /srv/www/example.com/logs/access.log

在此命令中,grep过滤所有以IP地址开头的行的Apache访问日志,后跟多个字符,一个空格,然后是字符200(其中200表示成功的HTTP连接)。-c选项仅输出匹配数的计数。要获取访问者的IP地址的输出以及请求成功请求的文件的路径,请省略-c标志:

grep -Eo "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.* 200"  /srv/www/example.com/logs/access.log

花括号指定模式的实例数。{1,3}要求前一个字符至少出现一次,但不超过三次。字符类[0-9]将与一个或多个数字匹配。您还可以生成类似的输出,但报告访问内容的尝试失败:

grep -Eo "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.* 404"  /srv/www/example.com/logs/access.log

以下命令将生成尝试连接到Web服务器的所有IP地址的列表。使用-o选项,只有匹配的字符串被发送到标准输出。uniq使用管道运算符(|)通过实用程序过滤此输出以过滤掉重复的条目:

grep -Eo "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" /srv/www/example.com/logs/access.log | uniq

下一个示例使用替代模式来匹配不同日志中的IP地址。以下命令在最近的/var/log/auth.log文件中搜索无效的登录尝试:

grep -Eo "Invalid user.*([0-9]{1,3}\.){3}[0-9]{1,3}" /var/log/auth.log

您可以将上述命令拆分为两层,以输出登录尝试失败的IP地址列表到您的系统:

grep "Invalid user" /var/log/auth.log | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}" | uniq

grep可以过滤命令的输出,例如tail -F提供对特定日志事件的实时监控:

tail ~/.procmail/procmail.log -F | grep "Subject"

在这种情况下,请tail遵循~/procmail/procmail.log文件。此输出传递给grep,它过滤流并仅打印包含字符串“Subject”的行。

使用Grep过滤命令

grep可以用来过滤长时间的帮助文件。这个命令过滤tar帮助文本,以更有效地找到处理bzip文件的选项::

tar --help | grep "bzip"

grep对于ls列出具有大量文件的目录内容时的输出也很有用:

ls /usr/lib | grep "xml"

使用zgrep grep压缩文件

zgrep命令的功能与上面的grep命令完全相同; 它在grep命令的基础增加了压缩和解压的功能:

zgrep -Eo "Invalid user.*([0-9]{1,3}\.){3}[0-9]{1,3}" /var/log/auth.log.2.gz

zgrep由于读取压缩文件的额外开销,操作所需的时间比grep操作长。

总结

怎样,你学会了嘛?赶快购买服务器尝试下吧! 想要学习更多相关知识,请访问腾讯云云+社区。


参考文献:《How to Grep for Text in Files》

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多