grep ( regex ) 中的正则表达式及其示例
Linux 附带 GNU grep,它支持扩展正则表达式。GNU grep 是所有 Linux 系统的默认设置。grep 命令用于查找存储在服务器或工作站上任何位置的信息。让我们了解正则表达式的基础知识以及如何在 Linux 和类 Unix 系统中使用正则表达式。
教程详细信息 | |
---|---|
难度等级 | 简单的 |
Root 权限 | 不 |
要求 | Linux 或 Unix 终端 |
类别 | 搜索 |
先决条件 | egrep 命令 |
操作系统兼容性 | BSD • Linux • macOS • Unix • WSL |
预计阅读时间 | 7 分钟 |
grep 中的正则表达式
正则表达式只不过是匹配每个输入行的模式。模式是字符序列。以下是模式的示例:
^w1 w1|w2 [^ ] foo bar [0-9]
三种类型的正则表达式
grep 理解三种不同类型的正则表达式语法:
- 基本 (BRE)
- 扩展 (ERE)
- perl(PCRE)
grep 正则表达式示例
在/etc/passwd文件中搜索名为“vivek”的单词:
$ grep 'vivek' /etc/passwd
示例输出:
vivek:x:1000:1000:Vivek Gite,,,:/home/vivek:/bin/bash vivekgite:x:1001:1001::/home/vivekgite:/bin/sh gitevivek:x:1002:1002::/home/gitevivek:/bin/sh
接下来,搜索名为 'vivek' 的单词(即不区分大小写搜索):
$ grep -i -w 'vivek' /etc/passwd
让我们尝试搜索两个单词 'vivek' 或 'raj':上例中的 PATTERN 用作扩展正则表达式。以下将使用egrep 命令
$ grep -E -i -w 'vivek|raj' /etc/passwd
匹配单词 Linux 或 UNIX :
$ egrep -i '^(linux|unix)' filename
# Same as above by passing the '-E' to the grep #
$ grep -E -i '^(linux|unix)' filename
egrep关于vs.grep -E语法的说明
最新版本的 egrep 会出现以下警告
egrep: warning: egrep is obsolescent; using grep -E Usage: grep [OPTION]... PATTERNS [FILE]... Try 'grep --help' for more information.
您需要更新所有脚本和命令以使用以下语法。从:
到(避免使用):
$ egrep -i 'foo|bar' /path/to/file
egrep
$ grep -E -i 'foo|bar' /path/to/file
如何匹配单个字符
该.字符(句点或点)与任意一个字符匹配。请考虑以下 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
让我们查找所有以 purchase 开头的文件名,输入:
$ grep 'purchase' demo.txt
接下来我需要查找所有以 purchase 开头且后跟另一个字符的文件名:
$ grep 'purchase.db' demo.txt
我们的最后一个例子是查找所有以 purchase 开头但以 db 结尾的文件名:
$ grep 'purchase..db' demo.txt
如何仅匹配点(.)
点 (.) 在正则表达式中具有特殊含义,即匹配任何字符。但是,如果您只需要匹配点 (.) 怎么办?我想告诉我的 grep 命令我想要实际的点 (.) 字符,而不是 . (点) 字符的正则表达式特殊含义。您可以在点 (.) 前面加上 \(反斜杠)来转义它:
$ grep 'purchase..' demo.txt
$ grep 'purchase.\.' demo.txt
锚点
您可以使用 ^ 和 $ 分别强制正则表达式仅在行首或行末匹配。以下示例仅显示以 vivek 开头的行:
$ grep ^vivek /etc/passwd
示例输出:
vivek:x:1000:1000:Vivek Gite,,,:/home/vivek:/bin/bash vivekgite:x:1001:1001::/home/vivekgite:/bin/sh
您只能显示以单词 vivek 开头的行,即不显示 vivekgite、vivekg 等:
$ grep -w ^vivek /etc/passwd
查找以单词 foo 结尾的行:
$ grep 'foo$' filename
仅匹配包含 foo 的行:
$ grep '^foo$' filename
您可以使用以下示例搜索空白行:
$ grep '^$' filename
匹配字符集
如何使用 grep 匹配字符集
点 (.) 可匹配任意单个字符。您可以使用 [..] 语法匹配特定字符和字符范围。假设您想要匹配“Vivek”或“vivek”:
$ grep '[vV]ivek' filename
或者
$ grep '[vV][iI][Vv][Ee][kK]' filename
让我们匹配数字和大小写字符。例如,尝试对 vivek1、Vivek2 等单词进行数学运算:
$ 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:]]– 小写字母:“abcdefghijklmnopqrstu vwxy z”。
- [[:space:]]– 空格字符:制表符、换行符、垂直制表符、换页符、回车符和空格。
- [[:upper:]]– 大写字母:“ABCDEFGHIJKLMNOPQRSTU VWXY Z”。
在此示例中,匹配所有大写字母:
$ 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 地址:
$ grep -E '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' file
如何搜索具有前导-符号的模式?
使用选项搜索与 ' --test--'匹配的所有行。如果没有,grep 将尝试将 ' ' 解析为选项列表。例如:-e-e–test–
$ grep -e '--test--' filename
如何用 grep 进行“或”运算?
使用以下语法:
或尝试以下语法:
$ grep -E 'word1|word2' filename
### OR ###
$ egrep 'word1|word2' filename
$ grep 'word1\|word2' filename
如何与 grep 进行 AND 操作?
使用以下语法显示包含“word1”和“word2”的所有行
$ grep 'word1' filename | grep 'word2'
,或者尝试以下语法:
$ grep 'foo.*bar\|word3.*word4' filename
如何测试序列?
您可以使用以下语法测试某个字符必须按序列重复的次数:
{N} {N,} {min,max}
匹配字符“v”两次:
$ egrep "v{2}" filename
以下将匹配“col”和“cool”两个单词:
$ 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 'vivek?' /etc/passwd |
* | 前一项将被匹配零次或多次 。 |
grep 'vivek*' /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 '^vivek' /etc/passwd grep '[^0-9]*' /etc/passwd |
$ | 匹配行尾的空字符串。 |
grep '^$' /etc/passwd |
\b | 匹配单词边缘的空字符串。 |
grep '\bvivek' /etc/passwd |
\B | 如果空字符串不在单词的边缘,则匹配该空字符串。 |
grep '\B/bin/bash' /etc/passwd |
\< | 匹配单词开头的空字符串 。 |
grep '\<vivek' /etc/passwd |
\> | 匹配单词末尾的空字符串 。 |
grep 'bash\>' /etc/passwd grep '\<vivek\>' /etc/passwd |
Linux grep 与 egrep 命令
egrep 与命令相同grep -E。它将 PATTERN 解释为扩展的正则表达式。摘自 grep 手册页:
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.
结论
您通过各种示例了解了如何在 Linux 或 Unix 上运行的 grep 中使用正则表达式 (regex)。请参阅此处的在线 GNU/grep 手册页,或使用 man 命令或 info 命令(或传递 --help 选项)查看以下资源:
$ man egrep
$ info egrep
$ man 7 regex
$ egrep --help