基本的grep命令语法

基本的grep命令语法如下:

grep 'word' filename
grep 'word' file1 file2 file3
grep 'string1 string2'  filename
cat otherfile | grep 'something'
command | grep 'something'
command option1 | grep 'data'
grep --color 'data' fileName

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

在第一个示例中,我将在Linux的passwd文件中搜索用户"tom"。要搜索/etc/passwd文件中的用户"tom",你需要输入以下命令:

grep tom /etc/passwd

以下是示例输出:

tom:x:1000:1000:tom,,,:/home/tom:/bin/bash

你可以指示grep忽略大小写,即匹配abc、Abc、ABC以及所有可能的组合,使用-i选项,如下所示:

grep -i "tom" /etc/passwd

Linux grep命令使用教程

grep的递归使用

如果你在目录层次结构中有一堆文本文件,例如/etc/apache2/中的Apache配置文件,并且你想找到定义特定文本的文件,那么使用grep命令的-r选项进行递归搜索。这将在目录/etc/apache2/及其所有子目录中对字符串"197.167.2.9"执行递归搜索操作(如下所示):

grep -r "mydomain.com" /etc/apache2/

或者,可以使用以下命令:

grep -R "mydomain.com" /etc/apache2/

以下是在Nginx服务器上进行类似搜索的示例输出:

grep -r "mydomain.com" /etc/nginx/
/etc/nginx/sites-available/mydomain.com.vhost:        if ($http_host != "www.mydomain.com") {

在这里,你会看到mydomain.com的结果在单独的行上,前面显示找到它的文件名(例如/etc/nginx/sites-available/mydomain.com.vhost)。通过使用-h选项可以轻松地抑制输出数据中文件名的包含(如下所述):grep -h -R "mydomain.com" /etc/nginx/。以下是示例输出:

grep -r "mydomain.com" /etc/nginx/
if ($http_host != "www.mydomain.com") {

使用grep仅搜索单词

当你搜索abc时,grep会匹配各种内容,例如kbcabc、abc123、aarfbc35等等,而不会遵守单词边界。你可以强制grep命令只选择那些包含完整单词匹配的行(即只匹配abc单词),如下所示:

grep -w "abc" file.txt

示例:

Linux grep命令使用教程

使用grep搜索两个不同的单词

要搜索两个不同的单词,你必须使用egrep命令,如下所示:

egrep -w 'word1|word2' /path/to/file

统计匹配单词的行数

grep命令具有报告每个文件中特定模式匹配次数的能力,使用-c(count)选项(如下所示):

grep -c 'word' /path/to/file

此外,用户可以使用'-n'选项在每行输出前面加上文本文件中获取该行的行号(如下所示):

grep -n 'root' /etc/passwd

以下是示例输出:

1:root:x:0:0:root:/root:/bin/bash

grep反向匹配

用户可以使用-v选项来反转匹配,这意味着它将只匹配那些不包含给定单词的行。例如,使用以下命令打印所有不包含单词par的行:

grep -v par /path/to/file

如何只列出匹配文件的名称

你必须使用-l选项来列出内容中提及特定单词的文件名,例如单词'primary',使用以下命令:

grep -l 'primary' *.c

最后,你可以使用以下命令强制grep以特定颜色显示输出:

grep --color root /etc/passwd

以下是示例输出:

Linux grep命令使用教程

如何让grep处理多个搜索模式

在某些情况下,你可能需要在给定文件(或一组文件)中搜索多个模式。在这种情况下,你应该使用grep提供的'-e'命令行选项。

例如,假设你想在当前工作目录中的所有文本文件中搜索单词"how"、"to"和"forge",你可以这样做:

grep -e how -e to -e forge *.txt

以下是该命令的运行效果:

Linux grep命令使用教程

'-e'命令行选项在模式以连字符(-)开头的情况下也很有帮助。例如,如果你想搜索"-how",那么以下命令将不起作用:

grep -how *.txt

当你使用-e命令行选项时,命令就能理解你到底在搜索什么:

grep -e -how *.txt

以下是两个命令的运行对比:

Linux grep命令使用教程

如何将grep输出限制为特定行数

如果你想将grep输出限制为特定的行数,可以使用'-m'命令行选项来实现。例如,假设你想在testfile1.txt中搜索单词"how",该文件包含以下行:

Linux grep命令使用教程

但要求是grep在找到3行包含搜索模式后就停止搜索。因此,你可以运行以下命令:

grep "how" -m3 testfile1.txt

以下是该命令的运行效果:

Linux grep命令使用教程

接下来,以下是该命令手册页中的说明:

If the input is standard input from a regular file, and NUM matching lines are output, grep ensures
that the standard input is positioned to just after the last matching line before exiting, regardless of the presence of trailing context lines. This enables a calling process to resume a search.

因此,例如,如果你有一个带有循环的bash脚本,并且你希望每次循环迭代获取一个匹配项,那么使用'grep -m1'就能满足需求。

如何让grep从文件获取搜索模式

如果你愿意,你也可以让grep命令从文件中获取模式。该工具的-f命令行选项可以让你这样做。

例如,假设你想在当前目录中的所有.txt文件中搜索单词"how"和"to",但希望通过一个名为"input"的文件来提供这些输入字符串,你可以这样做:

grep -f input *.txt

以下是该命令的运行效果:

Linux grep命令使用教程

如何让grep只显示完全匹配搜索模式的行

到目前为止,我们已经看到grep默认匹配并显示包含搜索模式的完整行。但如果要求是让grep只显示那些完全匹配搜索模式的行,可以使用'-x'命令行选项来实现。

例如,假设testfile1.txt文件包含以下行:

Linux grep命令使用教程

你要搜索的模式是"how are you?"。因此,要确保grep只显示完全匹配此模式的行,可以按以下方式使用:

grep -x "how are you?" *.txt

以下是该命令的运行效果:

Linux grep命令使用教程

如何强制grep不在输出中显示任何内容

在某些情况下,你可能不需要grep命令在输出中产生任何内容。你只想根据命令的退出状态知道是否找到了匹配项。这可以使用-q命令行选项来实现。

虽然-q选项会静默输出,但可以通过'echo $?'命令来确认工具的退出状态。在grep的情况下,当成功时(即找到了匹配项),命令以'0'状态退出;当没有找到匹配项时,以状态'1'退出。

以下截图显示了成功和失败的场景:

Linux grep命令使用教程

如何让grep显示不包含搜索模式的文件名

默认情况下,grep命令显示包含搜索模式的文件名(以及匹配的行)。这是合乎逻辑的,因为这正是对该工具的期望。然而,在某些情况下,需求可能是获取那些不包含搜索模式的文件的名称。

使用grep也可以实现这一点——-L选项可以让你这样做。例如,要查找当前目录中所有不包含单词"how"的文本文件,你可以运行以下命令:

grep -L "how" *.txt

以下是该命令的运行效果:

Linux grep命令使用教程

如何抑制grep产生的错误消息

你可以强制grep静默它在输出中显示的任何错误消息。这可以使用-s命令行选项来完成。例如,考虑以下场景,其中grep产生了与它遇到的目录相关的错误/警告:

Linux grep命令使用教程

在这种情况下,-s命令行选项就很有帮助。请看下面的效果。

Linux grep命令使用教程

可以看到错误/警告已被静默。

如何让grep递归搜索目录

从前一个要点中使用的示例可以清楚地看出,grep命令默认不会进行递归搜索。要确保你的grep搜索是递归的,请使用-d命令行选项并传递值'recurse'。

grep -d recurse "how" *

注意1:我们之前讨论的与目录相关的错误/警告消息也可以使用-d选项来静默——你只需要传递值'skip'。

注意2:使用'--exclude-dir=[DIR]'选项可以从递归搜索中排除匹配模式DIR的目录。

如何让grep用NULL字符终止文件名

如我们之前讨论的,grep的-l命令行选项用于当你只希望工具在输出中显示文件名时。例如:

Linux grep命令使用教程

现在,你应该知道上述输出中的每个名称都以换行符分隔/终止。以下是验证方法:

将输出重定向到文件,然后打印文件内容:

Linux grep命令使用教程

cat命令的输出确认了文件名之间存在换行符。

但正如你可能已经知道的,换行符也可能是文件名的一部分。因此,当处理文件名包含换行符并以换行符分隔/终止的情况时,对grep的输出进行操作就会变得困难(特别是通过脚本访问输出时)。

如果分隔/终止字符不是换行符就好了。好消息是,grep提供了一个命令行选项-Z,它确保文件名后面跟着一个NULL字符而不是换行符。

因此,在我们的例子中,命令变成:

grep -lZ "how" *.txt

以下是我们确认NULL字符存在的方法:

Linux grep命令使用教程

以下是一个相关的命令行选项,你应该了解:

 -z, --null-data
将输入视为一组行,每行以零字节(ASCII NUL字符)而不是换行符终止。与-Z或--null选项类似,此选项可以与sort -z等命令一起使用来处理任意文件名。

如何使用grep查找日志文件中的错误

在调试服务错误方面,grep是Linux管理员的瑞士军刀。大多数Linux服务都有日志文件来报告错误。这些日志文件可能非常大,而grep是一个多功能且快速的命令,可以搜索连接系统的IP地址、错误字符串或mail.log中受影响邮件用户的电子邮件地址。

示例:

搜索与特定电子邮件地址相关的连接。这里,'test@example.com'在服务器的mail.log文件中。

grep test@example.com /var/log/mail.log

结果:

Aug 22 09:45:10 mail dovecot: pop3-login: Login: user=<test@example.com>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17596, TLS, session=<3uoa5ffQovld3Uep>
Aug 22 09:45:10 mail dovecot: pop3(test@example.com)<17596><3uoa5ffQovld3Uep>: Disconnected: Logged out top=0/0, retr=1/6647, del=1/1, size=6630
Aug 22 09:45:10 mail dovecot: pop3-login: Login: user=<test@example.com>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17673, TLS, session=<fIIx6PfQkuBd3Uep>
Aug 22 09:45:10 mail dovecot: pop3(test@example.com)<17673><fIIx6PfQkuBd3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0
Aug 22 09:45:10 mail dovecot: pop3-login: Login: user=<test@example.com>, method=PLAIN, rip=192.168.0.112, lip=78.46.229.46, mpid=17868, TLS, session=<bd5L7ffQPsld3Uep>
Aug 22 09:45:10 mail dovecot: pop3(test@example.com)<17868><bd5L7ffQPsld3Uep>: Disconnected: Logged out top=0/0, retr=0/0, del=0/0, size=0
Aug 22 09:45:10 mail postfix/smtpd[6932]: NOQUEUE: reject: RCPT from unknown[1.2.3.4]: 504 5.5.2 <1.2.3.4>: Helo command rejected: need fully-qualified hostname; from=<test@example.com> to=<admin@example2.com> proto=ESMTP helo=<1.2.3.4>

要持续监控日志文件中此电子邮件地址的连接,可以结合tail和grep命令,如下所示:

tail -f /var/log/mail.log | grep test@example.com

要退出监控功能,按[Ctrl] + c键。