grep是 Linux 中用于文本处理的最有用和最强大的命令之一。grep在一个或多个输入文件中搜索与正则表达式匹配的行,并将每个匹配的行写入标准输出。
在本文中,我们将探讨如何在 GNU 版本中使用正则表达式的基础知识,该版本grep在大多数 Linux 操作系统中默认可用。
Grep 正则表达式
正则表达式或正则表达式是匹配一组字符串的模式。模式由具有特殊含义的运算符、构造文字字符和元字符组成。GNUgrep支持三种正则表达式语法,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
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash
在此示例中,字符串“bash”是一个基本的正则表达式,由四个文字字符组成。这告诉grep搜索具有“b”后紧跟“a”、“s”和“h”的字符串。
默认情况下,该grep命令区分大小写。这意味着大写和小写字符被视为不同。
要在搜索时忽略大小写,请使用-i选项(或--ignore-case)。
需要注意的是grep,将搜索模式作为字符串而不是单词来查找。因此,如果您正在搜索“gnu”,grep还将打印“gnu”嵌入较大单词的行,例如“cygnus”或“magnum”。
如果搜索字符串包含空格,则需要将其括在单引号或双引号中:
grep "Gnome Display Manager" /etc/passwd
锚定
锚点是元字符,可让您指定必须在行中的何处找到匹配项。
( ^caret) 符号与行首的空字符串匹配。在以下示例中,字符串“linux”仅在出现在行首时才会匹配。
grep '^linux' file.txt
($dollar)符号与行首的空字符串匹配。要查找以字符串“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-a]等价于[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} | 匹配前一项 fromn 到m 次。 |
(*星号)字符与前面的项目匹配零次或多次。以下将匹配“right”、“sright”、“ssright”等:
grep 'sright'
下面是更高级的模式,它匹配所有以大写字母开头并以句点或逗号结尾的行。正.则表达式匹配任意数量的任意字符:
grep -E '^[A-Z].*[.,]$' file.txt
(?问号)字符使前面的项目可选,它只能匹配一次。以下将匹配“明亮”和“正确”。?因为我们使用的是基本的正则表达式,所以该字符用反斜杠转义:
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 日志 错误文件中搜索所有出现的单词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
特殊反斜杠表达式
GNUgrep包含几个元字符,这些元字符由一个反斜杠和一个常规字符组成。下表显示了一些最常见的特殊反斜杠表达式:
表达 | 描述 |
---|---|
\b | 匹配单词边界。 |
\< | 匹配单词开头的空字符串。 |
\> | 匹配单词末尾的空字符串。 |
\w | 匹配一个单词。 |
\s | 匹配一个空格。 |
以下模式将匹配单独的单词“abject”和“object”。如果嵌入到较大的单词中,它将与单词不匹配:
grep '\b[ao]bject\b' file.txt
结论
正则表达式用于文本编辑器、编程语言和命令行工具,例如grep、sed和awk . 在搜索文本文件、编写脚本或过滤命令输出时,了解如何构造正则表达式非常有帮助。