Grep中的正则表达式(Regex)
grep
是Linux中最有用和强大的文本处理命令之一。grep
在一个或多个输入文件中搜索与正则表达式相匹配的行,并将每个匹配行写入标准输出。
在这篇文章中,我们将探讨如何在GNU版本的grep
中使用正则表达式的基本知识,GNU版本的grep
在大多数Linux操作系统中都是默认可用的。
Grep正则表达式
正则表达式或Rgex是一种匹配一组字符串的模式。模式由具有特殊含义的运算符、构造文字字符和元字符组成。GNU grep
支持三种正则表达式语法:基本语法、扩展语法和 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
锚点
锚点是元字符,允许您指定必须在行中的何处找到匹配项。
^
(插入符号)符号可以匹配行首的字符串。在下面的例子中,只有当字符串 "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"以外的任何字母、后跟"a"的字符串组合,如"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
所支持的量词。
*
(星号)字符与前面的项目匹配0次或多次。下面将匹配 "right","sright""ssright "等。
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
交替
交替这个词是一个简单的 "OR"。交替运算符|
(管道)允许你指定不同的可能匹配项,这些匹配可以是文字字符串或表达式集。这个运算符在所有正则表达式运算符中的优先级最低。
在下面的例子中,我们正在搜索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
包括几个元字符,它们由一个反斜杠和一个常规字符组成。下表显示了一些最常见的特殊反斜杠表达式。
以下模式将匹配单独的单词 "abject "和 "object"。如果这些词被嵌入到更大的词中,它将无法匹配。
grep '\b[ao]bject\b' file.txt
总结
正则表达式用于文本编辑器、编程语言和命令行工具,如grep
、sed
和awk
。在搜索文本文件、编写脚本或过滤命令输出时,知道如何构建正则表达式会非常有帮助。
如果你有任何问题或反馈意见,请随时留言。