grep是Linux中用于文本处理的最有用和功能最强大的命令之一。 grep在一个或多个输入文件中搜索与正则表达式匹配的行,并将每条匹配的行写入到标准输出。

在本教程中,我们将探讨如何在GNU版本grep中使用正则表达式的基础,该版本在大多数Linux操作系统中默认可用。我还介绍一些正则表达式的示例,比如,字符匹配,正则表达式符号,匹配单个字符,中括号表达式,量词,或运算,反斜杠表达式。

Grep正则表达式

正则表达式或正则表达式是与一组字符串匹配的模式。 模式由运算符,文字字符和元字符组成,它们具有特殊的含义。 GNU grep支持三种正则表达式语法Basic,Extended和Perl-compatible。

当没有给出正则表达式类型时,grep以Basic的形式调用,grep将搜索模式解释为基本Basic正则表达式。 要将模式解释为扩展Extended的正则表达式,请使用-E(或--extended-regexp)选项。

在GNU grep的实现中,基本正则表达式和扩展正则表达式语法之间在功能上没有区别。 唯一的区别是,在基本正则表达式中,元字符?+{|()被解释为文字字符。 为了在使用基本正则表达式时保持元字符的特殊含义,必须使用反斜杠(\)对字符进行转义。 稍后我们将解释这些和其他元字符的含义。

通常,您应始终将正则表达式括在单引号中,以避免shell解释和扩展元字符。

字符匹配

grep命令的最基本用法是在文件中搜索字符或一系列字符。 例如,要在 /etc/passwd文件中显示所有包含字符串“ bash”的行,请运行以下命令:

grep bash /etc/passwd

输出应如下所示:

root:x:0:0:root:/root:/bin/bash
myfreax:x:1000:1000:myfreax:/home/myfreax:/bin/bash

在此示例中,字符串“bash”是一个基本的正则表达式,由四个字符组成。 这告诉grep搜索带有紧随其后的“b”,“a”和“s”的“h”的字符串。

默认情况下,grep命令区分大小写。 这意味着将大写和小写字符视为不同的字符。要在搜索时忽略大小写,请使用-i选项(或--ignore-case)。

值得注意的是grep将搜索模式作为字符串而不是单词来查找。 因此,如果您要搜索“gnu”,grep还将打印在较大的单词中嵌入“gnu”的行,例如“cygnus”或“magnum”。如果搜索一个完全限定的字符串或者包含空格的字符串,则需要将其用单引号或双引号引起来:

grep "Gnome Display Manager" /etc/passwd

正则表达式符号

^符号与一行开头的字符串匹配。 在以下示例中,字符串“ linux”仅在出现在行的开头时才匹配。

grep '^linux' file.txt

$符号与行的结尾字符串匹配。 要找到以字符串“linux”结尾的行,可以使用:

grep 'linux$' file.txt

您还可以使用由^$构造的正则表达式。 例如,要查找仅包含“ linux”的行,请运行:

grep '^linux$' file.txt

另一个有用的例子是匹配所有空行的^$模式,即开头与结束都没有内容。

匹配单个字符

.符号是与任何单个字符匹配的元字符。 例如,要匹配以“ kan”开头,然后有两个字符并以字符串“roo”结尾的任何内容,则可以使用以下模式:

grep 'kan..roo' file.txt

中括号表达式

[]中括号表达式允许将字符括在中括号[]来匹配一组字符。 例如,找到包含“accept”或“accent”的行,可以使用以下表达式:

grep 'acce[np]t' file.txt

如果方括号内的第一个字符是符号^,则它将匹配方括号中未括起来的任何字符。 以下模式将匹配以“co”开头,除“l”之后为“la”之外的任何字母(例如“coca”,“cobalt”等)开头的任何字符串组合,但不匹配包含“cola”的行 ”:

grep 'co[^l]a' file.txt

您可以在括号内指定一系列字符,而不是一个一个地放置字符。 通过指定以连字符分隔的范围的第一个和最后一个字符来构造范围表达式。 例如,[a-e]等同于[abcde][1-3]等同于[123]。以下表达式匹配以大写字母开头的每一行:

grep '^[A-Z]' file.txt

grep还支持括号中包含的预定义字符类别。 下表显示了一些最常见的预定义字符:

量词 字符类
[:alnum:] 字母数字字符 。
[:alpha:] 字母字符。
[:blank:] 空格和制表符。
[:digit:] 数字。
[:lower:] 小写字母。
[:upper:] 大写字母。

要获取所有字符类别的完整列表,请参阅 Grep手册

量词

量词可让您指定要出现匹配项必须出现的次数。 下表显示了GNU grep支持的量词:

量词 描述
* 将前一项匹配零次或多次。
? 将前一项匹配零或一次。
+ 匹配前一项一次或多次。
{n} 精确匹配前一项n次
{n,} 至少匹配n次。
{,m} 最多匹配前一项m次。
{n,m} 匹配前一项从nm 次。

*字符与前面的字符匹配零次或多次。 以下将匹配“sright”,“right”等,

grep 's*right'

以下是更高级的模式,它匹配所有以大写字母开头,以句点或逗号结尾的行。 .*正则表达式匹配任意数量的任何字符:

grep -E '^[A-Z].*[.,]$' file.txt

?使前一字符成为可选,并且只能匹配一次。 以下内容将同时匹配“bright”和“right”。 ?字符以反斜杠转义,因为我们使用的是基本正则表达式:

grep 'b\?right' file.txt

以下是使用扩展正则表达式的正则表达式,不需要转义那些有特殊含义的字符:

grep -E 'b?right' file.txt

+字符与上一项匹配一次或多次。 以下将匹配“sright”和“ssright”,但不匹配“right”:

grep -E 's+right' file.txt

大括号字符{}允许您指定确切的数字,上限或下限或匹配次数必须在指定的范围。

以下匹配具有3到9位数字的所有整数:

grep -E '[[:digit:]]{3,9}' file.txt

或运算

或运算符|(竖线)使您可以指定不同的可能匹配项,这些匹配项可以是文字字符串或表达式集。 在所有正则表达式运算符中,此运算符的优先级最低。

在下面的示例中,我们搜索Nginx log错误文件中出现的单词fatalerrorcritical行:

grep 'fatal\|error\|critical' /var/log/nginx/error.log

如果使用扩展的正则表达式,则不应对|进行转义,如下所示:

grep -E 'fatal|error|critical' /var/log/nginx/error.log

分组

分组是正则表达式的一项功能,可让您将模式分组在一起并将其作为引用。 使用括号()创建分组。使用基本正则表达式时,必须用反斜杠(\)对括号进行转义。

以下示例同时匹配“fear”和“less”。 ?量词使(fear)组成为可选:

grep -E '(fear)?less' file.txt

反斜杠表达式

GNU grep包含几个由反斜杠和常规字符组成的元字符。 下表显示了一些最常见的特殊反斜杠表达式:

表达 说明
\b 匹配单词边界。
\< 匹配单词开头的空字符串。
\> 在单词末尾匹配一个空字符串。
\w 匹配一个单词。
\s 匹配空格。

以下模式将匹配单独的单词“abject”和“object”。 如果嵌入较大的单词,则不会匹配这些单词:

grep '\b[ao]bject\b' file.txt

结论

正则表达式常用于文本编辑器,编程语言和命令行工具,例如grepsedawk。 在搜索文本文件,编写脚本或过滤命令输出时,知道如何构造正则表达式会非常有帮助。如果您有任何问题或反馈,请随时发表评论。