grep
是Linux中用于文本处理的最有用和功能最强大的命令之一。grep
在一个或多个输入文件中搜索与正则表达式匹配的行,并将每条匹配的行写入到标准输出。
正则表达式是与一组字符串匹配的模式。模式由运算符,文字字符和元字符组成,它们具有特殊的含义。GNU grep
支持三种正则表达式语法Basic,Extended和Perl-compatible。
当没有给出正则表达式类型时,grep
以Basic的形式调用,grep
将搜索模式解释为基本Basic正则表达式。要将模式解释为扩展Extended的正则表达式,请使用-E
/--extended-regexp
选项。
在GNU grep
的实现中,基本正则表达式和扩展正则表达式语法之间在功能上没有区别,且两者一样。
唯一的区别是,在基本正则表达式中的元字符?
,+
,{
,|
,(
和)
被解释为文字字符,即不将这些字符作为正则解释。
为了在使用基本正则表达式时保持元字符的特殊含义,必须使用反斜杠\
对字符进行转义。稍后我们将解释这些和其他元字符的含义。
通常,您应始终将正则表达式括在单引号中,以避免shell解释和执行元字符在shell在意义。
字符匹配
grep
命令的最基本用法是在文件中搜索字符或字符串。除了在可以搜索文件的内容之外,grep还可以搜索标准输入的内容。
例如要搜索使用bash
作为默认的登录shell用户,则可以在/etc/passwd
文件中搜索包含bash
字符串的所有行。
以下grep
命令将搜索文件的内容,然后打印包含使用bash作为登录shell的用户:
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
行头与行尾
^
脱字符号表示与行的开头的字符串匹配。如果正则表达式以^
开头,grep
将在每行的开头开始匹配^
之后的字符串。
以下grep
命令将从文件file.txt
中搜索以字符串linux
开头的行:
grep '^linux' file.txt
$
美元符号与行的结尾字符串匹配。$
之后表示你需要搜索的内容。grep
将在每行的行尾匹配$
之后的字符串。
以下grep
命令将从文件file.txt
中搜索以字符串linux结尾的行:
grep 'linux$' file.txt
除了搜索行的开头和结尾,您还可以组合使用由^关键词$
构造的正则表达式。将允许搜索指定的内容,不是嵌入大字符串匹配的行。
另一个有用的例子是组合使用^$
模式匹配所有空行,即开头与结束都没有内容。这在查找空行时特别有用。
以下grep
命令将从文件file.txt
中搜索仅包含linux
的行:
grep '^linux$' file.txt
匹配单个字符
.
符号是与任何单个字符匹配的元字符。
例如,要包括kan,然后有两个字符并以字符串roo”结尾的任何内容,则可以使用以下模式:
grep 'kan..roo' file.txt
中括号表达式
[]
中括号表达式允许将字符括在中括号[]
来匹配一组字符。即从中括号[]
内的字符串任意使用一个字符来匹配行。
例如,以下grep
命令将从文件file.txt
中搜索包含accept
或accent
的行:
grep 'acce[np]t' file.txt
如果方括号内的第一个字符是符号^
,则它将匹配方括号中未括起来的任意字符。
以下模式将匹配包含除l
之外的co.a
字符串,.
表示任意字符。例如coca
,cobalt
的任意字符串组合,但不匹配包含cola
的行 。
例如,以下grep
命令将从文件file.txt
中搜索不cola
的行:
grep 'co[^l]a' file.txt
您可以通过指定以连字符分隔的范围的第一个和最后一个字符来构造范围表达式,在中括号表达式内指定一系列字符,而不是一个一个地写完所有字符。
例如,[a-e]
等同于[abcde]
,[1-3]
等同于[123]
。以下表达式匹配以大写字母开头的每一行:
grep '^[A-Z]' file.txt
grep
还支持中括号包含的预定义字符类别。[:alnum:]
表示匹配单个数字与字母字符,与[0-9A-Za-z]
一样。[:alpha:]
表示匹配单个字母字符,与[A-Za-z]
一样。
[:blank:]
表示匹配单个空格和制表符。[:digit:]
表示匹配单个数字0 1 2 3 4 5 6 7 8 9
。
[:lower:]表示匹配单个小写字母字符,与[a-z]
一样。[:upper:]表示匹配单个大写字母,与[A-Z]
一样。
量词
量词可让您指定匹配项必须出现的次数,即匹配关键词可以被多次匹配。以下是一些GNU grep
支持的量词。
*
表示匹配零次或者多次。?
表示将前一项匹配零或一次,+
表示匹配前一项一次或多次。{n}匹配前一项n
次,n
是数字。
{n,}
至少匹配n次。 {,m}
最多匹配前一项m次。 {n,m}匹配前一项必须出现次数是从n-m次,如果是{2,4},即2至4次。
现在我们已经了解正则表达式的量词,接下来我们将使用量词作为示例。在grep使用量词进行搜索,以及如何避免shell解释特殊字符*
,?
等。
*
字符与前面的字符匹配零次或多次。以下grep
命令示例将匹配sright
,right
,ssright
等。
正则表达式s*right
的*
量词表示匹配s字符零次或者多次,即没有上限,可以是很多sssss
。's*right'
给正则表达式使用单引号,也是避免shell解释特殊字符的方式。
echo right | grep 's*right'
echo ssright | grep 's*right'
以下是更高级的模式,它匹配所有以大写字母开头,以句点或逗号结尾的行。 .*
正则表达式表示匹配任意数量的任何字符。
以下grep
命令-E
选项表示使用扩展正则表达式。^
表示行的开始位置,[A-Z]
表示A到大Z:
grep -E '^[A-Z].*[.,]$' file.txt
?
使前一字符成为可选,并且只能匹配一次。以下grep命令将同时匹配bright
和right
。
你会这里的?
字符的前面多了反斜杠。如果你使用的是基本正则表达式则需要反斜杠转义?
字符避免shell的解释与执行。
grep 'b\?right' file.txt
以下grep -E
是使用扩展正则表达式的方式匹配'\b?right'
模式,因此不需要转义那些有特殊含义的字符。
grep -E 'b?right' file.txt
+
字符与上一项匹配一次或多次。 以下将匹配sright
和ssright
,但不匹配right
。
以下grep命令选项-E
表示使用扩展正则表达式,模式's+'
表示必须存在一个s
或者多个s
字符,没有上限。
grep -E 's+right' file.txt
大括号字符{}
允许您指定确切的数字,匹配次数必须在指定的范围内。以下grep命令将匹配3到9位数字的整数。
在以下'[[:digit:]]{3,9}'
模式中,[:digit:]表示0到9的数字,[[:digit:]]
则表示[0-9],{3,9}
表示匹配3到9次,即可行必须包含有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
分组
分组是正则表达式的一项功能,可让您将模式分组并将其作为引用。可使用括号()
创建分组。使用基本正则表达式时,必须用反斜杠\
对括号进行转义。
正则表达式可以有多个组。结果,匹配捕获的组通常保存在数组中,数组的成员与匹配的组顺序相同。这通常只是匹配组本身的顺序。
匹配的组保存在数组中,如果需要对捕获的组进行引用。可使用$1, ..., $9
对捕获的组进行引用。
以下示例同时匹配fear
和less
。 量词?
使(fear)
组成为可选。
grep -E '(fear)?less' file.txt
反斜杠表达式
GNU grep
包含几个由反斜杠和常规字符组成的元字符。以下是一些最常见的特殊反斜杠表达式。
\b
匹配单词边界。<
匹配单词开头的空字符串。>
在单词末尾匹配一个空字符串。 \w
匹配一个单词。\s
匹配空格。
以下模式将匹配单独的单词abject
和object
。 如果嵌入较大的单词,则不会匹配这些单词:
grep '\b[ao]bject\b' file.txt
结论
正则表达式常用于文本编辑器,编程语言和命令行工具,例如grep
,sed
和awk
。 在搜索文本文件,编写脚本或过滤命令输出时,知道如何构造正则表达式会非常有帮助。如果您有任何问题或反馈,请随时发表评论。