grep(regex)中的正则表达式和示例
在Linux和类似Unix的操作系统上,如何在正则表达式中使用grep命令?
如何在Linux中使用grep和正则表达式(regex)搜索文本/单词?
Linux随附GNU grep,它支持扩展的正则表达式。
GNU grep是所有Linux系统上的默认设置。
grep命令用于查找存储在服务器或工作站上任何地方的信息。
让我们看一下正则表达式的基础知识,以及如何在Linux和Unix之类的系统中使用正则表达式。
grep中的正则表达式
正则表达式不过是每个输入行要匹配的模式。
模式是字符序列。
以下是模式的示例:
^w1 w1|w2 [^ ] foo bar [0-9]
三种正则表达式
grep可以理解三种不同类型的正则表达式语法,如下所示:
- 基本(BRE)
- 扩展(ERE)
- perl(PCRE)
grep正则表达式示例
在/etc/passswd中搜索Hyman
grep 'Hyman' /etc/passwd
输出示例:
Hyman:x:1000:1000:,,,:/home/Hyman:/bin/bash Hymangite:x:1001:1001::/home/Hymangite:/bin/sh giteHyman:x:1002:1002::/home/giteHyman:/bin/sh
在任何情况下都可以搜索Hyman(即不区分大小写的搜索)
grep -i -w 'Hyman' /etc/passwd
在任何情况下都可以搜索Hyman或raj
grep -E -i -w 'Hyman|raj' /etc/passwd
最后一个示例中的PATTERN用作扩展的正则表达式。
在任何情况下,以下内容都将与单词Linux或UNIX相匹配:
egrep -i '^(linux|unix)' filename
如何匹配单个字符
.字符(句点或点)与任何一个字符匹配。
考虑以下demo.txt文件:
$ cat demo.txt
输出示例:
foo.txt bar.txt foo1.txt bar1.doc foobar.txt foo.doc bar.doc dataset.txt purchase.db purchase1.db purchase2.db purchase3.db purchase.idx foo2.txt bar.txt
让我们查找所有从购买开始的文件名:
grep 'purchase' demo.txt
接下来,我需要找到所有文件名,从购买开始,然后是另一个字符:
grep 'purchase.db' demo.txt
我们的最后一个示例查找所有以购买开始但以db结尾的文件名:
grep 'purchase..db' demo.txt
如何仅匹配点字符
点(.)在正则表达式中有特殊含义,即匹配任何字符。
但是,如果只需要匹配点(.)怎么办?
我想告诉我的grep命令,我需要实际的点(.)字符,而不是的正则表达式特殊含义。
您可以在点(.)前面加上(反斜杠),以使其转义:
grep 'purchase..' demo.txt grep 'purchase.\.' demo.txt
锚点
您可以使用^和$来强制正则表达式分别仅在行的开头或结尾进行匹配。
以下示例显示仅以插孔开头的行:
grep ^Hyman /etc/passwd
输出示例:
Hyman:x:1000:1000:,,,:/home/Hyman:/bin/bash Hymangite:x:1001:1001::/home/Hymangite:/bin/sh
您只能显示仅以单词Hyman开头的行,即不显示Hymangite,Hymang等:
grep -w ^Hyman /etc/passwd
查找以foo结尾的行:
grep 'foo$' filename
匹配仅包含foo的行:
grep '^foo$' filename
您可以使用以下示例搜索空白行:
grep '^$' filename
如何使用grep匹配字符集
点字符(.)匹配任何单个字符。
您可以使用[..]语法匹配特定字符和字符范围。
假设您要同时匹配插孔或插孔:
grep '[vV]ivek' filename
或者
grep '[vV][iI][Vv][Ee][kK]' filename
让我们匹配数字以及大小写字符。
例如,尝试对诸如Hyman1,Hyman2之类的单词进行数学运算:
grep -w '[vV]ivek[0-9]' filename
在此示例中,匹配两个数字。
换句话说,匹配foo11,foo12,foo22等,执行:
grep 'foo[0-9][0-9]' filename
您不限于数字,可以匹配至少一个字母:
grep '[A-Za-z]' filename
显示所有包含w或n字符的行:
grep [wn] filename
在方括号表达式中,用[:和:]括起来的字符类的名称代表该类所有字符的列表。
标准字符类名称为:
[[:alnum:]]
字母数字字符。[[:alpha:]]
字母字符[[:blank:]]
空白字符:空格和制表符。[[:digit:]]
数字:0 1 2 3 4 5 6 7 8 9。[[:lower:]]
小写字母:a b c d e f g h i j k l m n o p q r s t u v w x y z。[[:space:]]
空格字符:制表符,换行符,垂直制表符,换页,回车和空格。[[:upper:]]
大写字母:A B C D E F G H I J K L M N O P Q R S T U V W X YZ。
在此示例中,匹配所有大写字母:
grep '[:upper:]' filename
如何否定集合中的匹配
^否定集合中的所有范围:
grep '[vV]ivek[^0-9]' test
使用grep正则表达式搜索文本模式
通配符
您可以使用。
进行单个字符匹配。
在此示例中,匹配所有以b开头并以t结尾的3个字符的单词:
grep '\<b.t\>' filename
其中:
- \ <匹配单词开头的空字符串
- >匹配单词末尾的空字符串。
用正好两个字符打印所有行:
grep '^..$' filename
显示以点和数字开头的任何行:
grep '^\.[0-9]' filename
转义点
假设您只想匹配IP地址192.168.2.254,仅此而已。
以下用于查找IP地址192.168.1.254的正则表达式将不起作用(还记得点匹配任何单个字符吗?
):
grep '192.168.1.254' hosts
输出示例:
192.168.2.18 centos7 192x168y2z18 centos7
所有三个点都需要转义:
192.168.2.18 centos7
grep '192\.168\.1\.254' hosts
以下示例仅匹配一个IP地址:
egrep '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' file
如何搜索具有前导符号的模式?
使用-e选项搜索所有与test匹配的行如果不使用-e,grep会尝试将test解析为选项列表:
grep -e '--test--' filename
我该怎么办或使用grep?
使用以下语法:
grep -E 'word1|word2' filename ### OR ### egrep 'word1|word2' filename
或者
grep 'word1\|word2' filename
如何与grep结合使用?
使用以下语法显示同时包含word1和word2的所有行
grep 'word1' filename | grep 'word2'
或者
grep 'foo.*bar\|word3.*word4' filename
如何测试序列?
您可以使用以下语法测试字符必须按顺序重复的频率:
{N} {N,} {min,max}
匹配字符v两次:
egrep "v{2}" filename
以下将同时匹配col和酷词:
egrep 'co{1,2}l' filename
我们的下一个示例将匹配至少三个字母c的任何行。
egrep 'c{3,}' filename
在此示例中,我将匹配以下格式的手机号码91-1234567890(即TwoDigit-TenDigit)
grep "[[:digit:]]\{2\}[ -]\?[[:digit:]]\{10\}" filename
如何使用grep突出显示?
传递--color
如下:
grep --color regex filename
如何仅显示匹配项而不是整行?
使用以下语法:
grep -o regex filename
grep正则表达式运算符
我希望下表可以帮助您在Linux或类似Unix的系统上使用时快速理解grep中的正则表达式:
运算符 | 意义 | 例子 |
---|---|---|
. | 匹配任何单个字符。 | grep '.' file |
grep 'foo.' input
? | 上一项是可选的,最多匹配一次。 | grep 'igift?' /etc/passwd
* | 前一项将被匹配零次或多次。 | grep 'igift*' /etc/passwd
+ | 前一项将被匹配一次或多次。 | ls /var/log/ | grep -E "^[a-z]+.log."
{N} | 上一项完全匹配N次。 | egrep '[0-9]{2} input
{N,} | 前一项匹配N次或更多次。 | egrep '[0-9]{2,} input
{N,M} | 前一项至少匹配N次,但不超过M次。 | egrep '[0-9]{2,4} input
- | 表示范围,如果它不是列表中的第一个或最后一个,也不是列表中某个范围的终点。 | grep ':/bin/[a-z]*' /etc/passwd
^ | 匹配行首的空字符串;也代表不在列表范围内的字符。 | grep '^igift' /etc/passwd
grep '[^0-9]*' /etc/passwd
$ | 匹配行尾的空字符串。 | grep '^$' /etc/passwd
\b | 匹配单词边缘的空字符串。 | grep '\bigift' /etc/passwd
\B | 匹配空字符串,前提是它不在单词的边缘。 | grep '\B/bin/bash /etc/passwd
\< | 匹配单词开头的空字符串。 | grep '\'
\> | 匹配单词末尾的空字符串。 | grep 'bash\>' /etc/passwd
Linux grep vs egrep命令
egrep与grep -E
命令相同。
它将PATTERN解释为扩展的正则表达式。
In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(, and \). Traditional egrep did not support the { meta-character, and some egrep implementations support \{ instead, so portable scripts should avoid { in grep -E patterns and should use [{] to match a literal {. GNU grep -E attempts to support traditional usage by assuming that { is not special if it would be the start of an invalid interval specification. For example, the command grep -E '{1' searches for the two-character string {1 instead of reporting a syntax error in the regular expression. POSIX.2 allows this behavior as an extension, but portable scripts should avoid it.