Linux Shell :正则表达式

先来看一句 Shell 代码:

dpkg --list | grep -E -o 'cuda-documentation-[0-9\-]*'
  1. dpkg --listdpkg 是 Debian 系列 Linux 发行版(如 Ubuntu)的包管理工具。--list 选项用于列出所有已安装的软件包。

  2. | :这是一个管道符号,用于将前一个命令的输出作为后一个命令的输入。在这里,dpkg --list 的输出被直接传递给 grep 命令。

  3. grep -E -o 'cuda-documentation-[0-9\-]*'grep 是一个用于在文本中搜索匹配某个模式的命令。

    • -E:这是一个选项,用于启用扩展的正则表达式匹配。
    • -o:这个选项告诉 grep 只输出匹配的部分,而不是整行。
    • 'cuda-documentation-[0-9\-]*':这是要搜索的模式。它匹配任何以“cuda-documentation-”开头,后面跟着 0 个或多个数字或短横线(-)的字符串。

在这里 [0-9\-]* 就是正则表达式。

正则表达式 用来指定字符串的 模式,经常用于搜索-替换操作。

Regular expressions are used to specify patterns of characters。

这里,术语 模式 (pattern),是指一种用于解决特定问题的、可重复使用的解决方案。模式是一种经过验证的、解决特定问题的最佳实践。

在正则表达式中,普通字符匹配自身,特定字符拥有特殊的含义,这些特定字符称为 元字符

元字符 是指有特殊含义的字符。比如字符 ~ 在文本中表示“波浪号”,但在 Shell 环境中,~ 是一个元字符,表示 home 目录。如果要从字面上使用它们,则需要转义,要用到表示转义的元字符 \ ,像 \~ 这样。对比下面的例子:

echo ~

输出:/home/nano

echo \~

输出:~

下面开始介绍正则表达式中的元字符,这也是正则表达式的语法。

正则表达式语法汇总

基本匹配元字符

基本匹配元字符 含义
. 除新行(newline:\n)字符外,匹配任意的单个字符
^ 锚:匹配行的开头
$ 锚:匹配行的末尾
\< 锚:匹配单词的开头
\> 锚:匹配单词的末尾
[list] 字符类:匹配 list 中的任何一个字符
[^list] 字符类:匹配不在 list 中的任何一个字符
() 组(group):视为一个单独的单元
| 或(alternation):匹配选择任意一个
\ 引用(quote):从字面上解释元字符

注1:锚(anchor),指定正则表达式的开头和结尾,从而匹配特定的字符串或文本。
注2:字符类(character class),在正则表达式中,可以使用方括号([])来定义一个字符类。字符类可以包含一个或多个字符。
注3:引用(quote),它指的是通过特定字符或语法将文本包围起来,以保护文本中的特殊字符不受解释或转义。比如在正则表达式语法中,$ 表示匹配行的末尾,如果想查找的字符串中包含这个符号时怎么办?这时要用 引用 ,即用 \$ 来表示美元符号。

运算符元字符

运算符元字符 含义
* 匹配(match) 0 次或多次
+ 匹配 1 次或多次
? 匹配 0 次或 1 次
{n} 限定(bound):匹配 n 次
{n,} 限定:最少匹配 n 次
{,m} 限定:最多匹配 m 次
{n,m} 限定:最少匹配 n 次,最多匹配 m 次

预定义字符类

字符类 含义 类似于
[:lower:] 小写字母 a-z
[:upper:] 大写字母 A-Z
[:alpha:] 大小写字母 A-Za-z
[:alnum:] 大小写字母、数字 A-Za-z0-9
[:digit:] 数字 0-9
[:punct:] 标点符号 -
[:blank:] 空格或制表符 -

使用总则

为了创建正则表达式,需要根据特定的规则将普通字符和元字符组合在一起,然后使用该正则表达式搜索希望查找的字符串

使用举例

匹配任意的单个字符: .

grep 'Har..y' data.txt

搜索文件 data.txt ,查找类似于以下单词的
harley、harxxy、har12y

匹配行:^$

假设 data.txt 文件中有以下 4 行内容:

Harley is smart
Harley
I like Harley
the dog likes the cat

  1. 普通查找
grep 'Harley' data.txt

将输出以下三行:

Harley is smart
Harley
I like Harley

  1. 而如果正则表达式使用 ^ 锚定为匹配行的开头,代码如下:
grep '^Harley' data.txt

将输出以下两行:

Harley is smart
Harley

之所以不选取第三行,是因为第三行中的 Harley 不在一行的开头部分。

  1. 如果正则表达式使用 $ 锚定为匹配行的结尾,代码如下:
grep 'Harley$' data.txt

将输出以下两行:

Harley
I like Harley

之所以不选取第一行,是因为第一行中的 Harley 不在行的结尾部分。

  1. 同时锚定行首和行尾
grep '^Harley$' data.txt

搜索整行就一个单词“Harley”的行,输出:

Harley

小技巧:
grep ‘^$’ data.txt | wc -l
这个命令将统计在 data.txt 文件中的空行数量。

匹配单词:\<\>

grep '\ data.txt      # 以“kn”为开头的单词所在行
grep 'ow\>' data.txt      # 以“ow”为结尾的单词所在行
grep '\' data.txt  # 包含单词 “know” 的行

需要注意的是,当使用正则表达式时,单词 的定义要比英语中的定义更灵活。在正则表达式中,单词就是一个由字母、数字或者下划线(_)构成的连续字符序列,比如 error_code_5 是合法的单词。

匹配字符类:[list][^list]

. 匹配的是任意的字符,如果需要匹配特定字符,可以将这些字符放在方括号([])中来指定希望搜索的字符。这样的结构就称为一个字符类。

grep 'H[aA]' data.txt

搜索文件 data.txt ,查找所有包含字符 “Ha” 或 “HA” 的

如果特定的字符是一个连续范围,则可以将第一个字符和最后一个字符用连字符(-)分开:

grep 'H[0-9]' data.txt

搜索文件 data.txt ,查找所有包含字符 “H0” 、 “H1” 、… “H9” 的

匹配不在字符类中的字符,只需要在开头的左方括号之后放一个音调符号(^)即可:

grep 'H[^aA]' data.txt

搜索文件 data.txt ,查找所有包含字符 ‘X’,同时后面不跟有 “a” 或 “A”的

预定义字符类:[:xxxx:]

字符类 的特殊用法,预定义一些常用的字符集。

grep '21[[:alpha:]]' data.txt

搜索文件 data.txt ,查找所有包含数字 “21”,后面跟一个小写字母或大写字母的所有行。
注意必须包含第二组方括号。
另外记住的是:每一个预定义字符类只表示一个单独的字符

重复运算符:*+?

grep ':.*:' data.txt  	#包含 1 个冒号,后跟 0 个或多个任意字符,后面再跟 1 个冒号
grep ':.+:' data.txt  	#包含 1 个冒号,后跟 1 个或多个任意字符,后面再跟 1 个冒号
grep ':.?:' data.txt  	#包含 1 个冒号,后跟 0 个或 1 个任意字符,后面再跟 1 个冒号

限定运算符:{n}{n,}{,m}{n,m}

grep '[0-9]{3}' data.txt	#正好匹配 3 个数字
grep '[0-9]{3,}' data.txt	#至少匹配 3 个数字
grep '[0-9]{,5}' data.txt	#最多匹配 5 个数字
grep '[0-9]{3,5}' data.txt	#匹配 3~5 个数字

组(())和或(|

如果希望在文件中搜索包含下述任意一个单词的行:

cat dog bird hamster

可以使用如下命令:

grep '\<(cat|dog|bird|hamster)\>' data.txt

注意使用圆括号(())创建一个组,这将允许我们将整个模式视为一个单元。

你可能感兴趣的:(Linux,1024程序员节)