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》