如何在Linux上使用grep命令
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的输出进行排序。
我们获得了按文件大小的升序排列的所有文件的排序列表,这些文件在八月(不考虑年份)中进行了修改。