Grep(Regex)中的正则表达式

时间:2020-03-05 15:29:15  来源:igfitidea点击:

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

在本文中,我们将探讨如何在GNU版本的'grep'中使用正则表达式的基础,大多数Linux操作系统默认情况下都提供此功能。

Grep正则表达式

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

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

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

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

文字匹配

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

grep bash /etc/passwd

输出应如下所示:

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

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

默认情况下,“ grep”命令区分大小写。
这意味着将大写和小写字符视为不同的字符。

要在搜索时忽略大小写,请使用'-i'选项(或者'--ignore-case')。

重要的是要注意,“ grep”将搜索模式视为字符串,而不是单词。
因此,如果我们要搜索“ gnu”,则“ grep”还将打印“ gnu”嵌入较大字词(例如“天鹅座”或者“大酒瓶”)的行。

如果搜索字符串包含空格,则需要将其用单引号或者双引号引起来:

grep "Gnome Display Manager" /etc/passwd

锚定

定位符是元字符,可让我们指定必须在该行中找到匹配项的位置。

'^'(脱字符号)符号与一行开头的空字符串匹配。
在下面的示例中,仅当字符串“ linux”出现在行的开头时才匹配。

grep '^linux' file.txt

“ $”(美元)符号与行首的空字符串匹配。
要找到以字符串“ linux”结 tail的行,可以使用:

grep 'linux$' file.txt

我们还可以使用两个锚点构造一个正则表达式。
例如,要查找仅包含“ linux”的行,请运行:

grep '^linux$' file.txt

另一个有用的示例是匹配所有空行的'^ $'模式。

匹配单个字符

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

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-a]”等效于“ [abcde]”,而“ [1-3]”等效于“ [123]”。

以下表达式匹配以大写字母开头的每一行:

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

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

量化器字符类
'[:Alnum:** '字母数字字符。
'[:Alpha:** '字母字符。
'[:空白:** '空间和标签。
'[:Digit:** '数字。
'[:下部:** '小写字母。
'[:Upper:** '大写字母。

有关所有字符类的完整列表,请参阅Grep手册。

量词

量词允许我们指定要出现的匹配项必须出现的项数。
下表显示了GNU'grep'支持的量词:

量化器描述
'*'将前面的项目与零或者多次匹配。
'?'将前面的项目匹配为零或者一次。
'+'匹配前面的项目一次或者多次。
'{n}'匹配前面的项目完全是'n'次。
'{n,}'匹配前面的项目至少为'n'次。
'{,m}'将前面的项目与大多数人的次数匹配。
'{n,m}'将前面的项目与“N”与“M”匹配匹配。

“ *”(星号)字符与前面的项目匹配零次或者多次。
以下将匹配“正确”,“正确”,“正确”等等。

grep 's*right'

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

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

这 '?' (问号)字符使前一项为可选,并且只能匹配一次。
以下内容将同时匹配“亮”和“右”。
这 '?'字符以反斜杠转义,因为我们使用的是基本的正则表达式:

grep 'b\?right' file.txt

这是使用扩展正则表达式的正则表达式:

grep -E 'b?right' file.txt

“ +”(加号)字符与前面的项目匹配一次或者多次。
以下将匹配“正确”和“正确”,但不匹配“正确”:

grep -E 's+right' file.txt

大括号字符“ {}”允许我们指定确切的数字,上限或者下限或者发生匹配必须发生的范围。

以下内容匹配3到9位之间的所有整数:

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

轮换

术语“交替”是一个简单的“或者”。
交替运算符“ |” (竖线)允许我们指定不同的可能匹配项,这些匹配项可以是文字字符串或者表达式集。
在所有正则表达式运算符中,此运算符的优先级最低。

在下面的示例中,我们正在Nginx日志错误文件中搜索单词'fatal','error'和'critical'的所有出现:

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

如果使用扩展的正则表达式,则运算符'|'不应逃脱,如下所示:

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

分组

分组是正则表达式的一项功能,可让我们将模式分组在一起并将它们作为一项引用。
使用括号'()'创建组。

使用基本正则表达式时,必须在括号中使用反斜杠('')进行转义。

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

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

反斜杠特殊表达式

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

表达描述
'\ b'匹配一个字边界。
'\ <'匹配单词开头的空字符串。
'>'匹配单词末尾的空字符串。
'\ w'匹配一个单词。
'\ s'匹配一个空间。

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

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