如何在Linux上使用grep命令

时间:2020-01-09 10:39:54  来源:igfitidea点击:

Linux的grep命令是一个字符串和模式匹配实用程序,它显示来自多个文件的匹配行。它也可以与其他命令的管道输出一起使用。

使用grep进行简单搜索

要在文件中搜索字符串,请在命令行中传递搜索词和文件名:


显示匹配行。在这种情况下,它是一行。匹配的文本突出显示。这是因为在大多数发行版中,grep被别名为:

alias grep='grep --colour=auto'

让我们看一下有多行匹配的结果。我们将在应用程序日志文件中查找单词Average。因为我们无法记住日志文件中的单词是否为小写字母,所以我们将使用-i(忽略大小写)选项:

grep -i Average data-1.log

显示每条匹配的行,并在每行中突出显示匹配的文本。

我们可以使用-v(反转匹配)选项显示不匹配的行。

grep -v Mem data-1.log

没有突出显示,因为这些是不匹配的行。

我们可以使grep完全保持沉默。结果从grep返回到shell。结果为零表示找到了字符串,结果为1表示未找到字符串。我们可以使用$?特殊参数来检查返回码:

grep -q average data-1.log
echo $?
grep -q theitroad data-1.log
echo $?

用grep进行递归搜索

要搜索嵌套目录和子目录,请使用-r(递归)选项。请注意,我们没有在命令行上提供文件名,而必须提供路径。在这里,我们正在当前目录中搜索。以及任何子目录:

grep -r -i memfree .

输出包括每个匹配行的目录和文件名。

我们可以通过使用-R(递归取消引用)选项使grep遵循符号链接。在此目录中,我们有一个符号链接,称为" logs-folder"。它指向/ home / dave / logs

ls -l logs-folder

让我们使用-R(递归取消引用)选项重复上一次搜索:

grep -R -i memfree .

跟随符号链接,grep也搜索它指向的目录。

搜索整个词

默认情况下,如果搜索目标出现在该行的任何位置,包括另一个字符串内,则" grep"将与该行匹配。看这个例子。我们将搜索"免费"一词。

grep -i free data-1.log

结果是其中包含自由字符串的行,但是它们不是分开的单词。它们是字符串MemFree的一部分。

要强制grep仅匹配单独的单词,请使用-w(单词regexp)选项。

grep -w -i free data-1.log
echo $?

这次没有结果,因为免费搜索词不会在文件中显示为单独的单词。

使用多个搜索词

-E(扩展的regexp)选项使我们可以搜索多个单词。 (-E选项替换了grep不推荐的egrep版本。)

该命令搜索两个搜索词,average和memfree。

grep -E -w -i "average|memfree" data-1.log

将显示每个搜索词的所有匹配行。

我们还可以搜索不一定是整个单词的多个术语,但也可以是整个单词。

-e(模式)选项允许我们在命令行上使用多个搜索词。我们正在使用正则表达式括号功能来创建搜索模式。它告诉grep匹配括号[]中包含的任何字符。这意味着grep在搜索时将匹配kB或者KB。

两个字符串都匹配,实际上,某些行包含两个字符串。


精确匹配线

-x(行正则表达式)将只匹配整行与搜索词匹配的行。让我们搜索一个我们知道在日志文件中仅出现一次的日期和时间戳:

grep -x "20-Jan--06 15:24:35" data-1.log

找到并显示匹配的单行。

相反的是仅显示不匹配的行。当我们查看配置文件时,这可能很有用。注释很棒,但是有时很难其中找到实际设置。这是/ etc / sudoers文件:

我们可以像这样有效地过滤掉注释行:

sudo grep -v "#" /etc/sudoers

这很容易解析。

仅显示匹配文本

在某些情况下,我们可能不想仅看到匹配的文本,而不会看到整个匹配的行。 -o(仅匹配)选项可以做到这一点。

grep -o MemFree data-1.log

显示减少为仅显示与搜索词匹配的文本,而不是整个匹配行。

用grep计数

grep不仅涉及文本,还可以提供数字信息。我们可以用不同的方式使grep对我们很重要。如果我们想知道搜索词在文件中出现多少次,可以使用-c(计数)选项。

grep -c average data-1.log

grep报告说,搜索词在该文件中出现了240次。

我们可以使用-n(行号)选项使grep显示每个匹配行的行号。

grep -n Jan data-1.log

每条匹配行的行号显示在该行的开头。

要减少显示的结果数,请使用-m(最大计数)选项。我们将输出限制为五个匹配行:

grep -m5 -n Jan data-1.log

添加上下文

能够看到一些其他行,可能是每条匹配行的不匹配行通常很有用。它可以区分哪些匹配的行是我们感兴趣的行。

要在匹配行之后显示一些行,请使用-A(在上下文之后)选项。在此示例中,我们要求输入三行:

grep -A 3 -x "20-Jan-06 15:24:35" data-1.log

要查看匹配行之前的一些行,请使用-B(在上下文之前)选项。

grep -B 3 -x "20-Jan-06 15:24:35" data-1.log

要包含匹配行之前和之后的行,请使用-C(上下文)选项。

grep -C 3 -x "20-Jan-06 15:24:35" data-1.log

显示匹配文件

要查看包含搜索词的文件的名称,请使用-l(匹配文件)。要找出哪些C源代码文件包含对sl.h头文件的引用,请使用以下命令:

grep -l "sl.h" *.c

列出了文件名,而不是匹配的行。

当然,我们可以查找不包含搜索词的文件。 -L(不匹配文件)选项就是这样做的。

grep -L "sl.h" *.c

行的开始和结束

我们可以强制grep只显示在行的开头或者结尾的匹配项。 ^正则表达式运算符匹配行的开头。实际上,日志文件中的所有行都将包含空格,但是我们将搜索以空格作为第一个字符的行:

grep "^ " data-1.log

在显示的线性起始处以空格作为第一个字符的行。

要匹配行尾,请使用$正则表达式运算符。我们将搜索以00结尾的行。

grep "00$" data-1.log

显示屏显示以00结尾的行。

在grep中使用管道

当然,我们可以通过管道将输入传递给grep,将来自grep的输出传递给另一个程序,然后将grep嵌套在管道链中间。

假设我们要查看C源代码文件中所有出现的stringExtractParameters。我们知道将会有很多,所以我们将输出传递给less

grep "ExtractParameters" *.c | less

输出以less表示。

这使我们可以浏览文件列表并使用less的搜索功能。

如果我们将grep的输出通过管道传送到wc并使用-l(lines)选项,我们可以计算包含ExtractParameters的源代码文件中的行数。 (我们可以使用-grep -c (count)选项来实现,但这是演示从grep出来的管道的一种简洁方法。)

grep "ExtractParameters" *.c | wc -l

使用下一条命令,我们将来自ls的输出传递给grep,并将来自grep的输出传递给sort。我们将列出当前目录中的文件,选择其中包含字符串Aug的文件,然后按文件大小对其进行排序:

ls -l | grep "Aug" | sort +4n

让我们分解一下:

  • ls -l:使用ls执行文件的长格式列表。

  • grep Aug:从ls列表中选择包含Aug的行。请注意,这还将查找名称中具有Aug的文件。

  • sort + 4n:在第四列(文件大小)上对grep的输出进行排序。

我们获得了按文件大小的升序排列的所有文件的排序列表,这些文件在八月(不考虑年份)中进行了修改。