• Linux Shell :正则表达式


    先来看一句 Shell 代码:

    dpkg --list | grep -E -o 'cuda-documentation-[0-9\-]*'
    
    • 1
    1. dpkg --listdpkgDebian 系列 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 ~
    
    • 1

    输出:/home/nano

    echo \~
    
    • 1

    输出:~

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

    正则表达式语法汇总

    基本匹配元字符

    基本匹配元字符含义
    .除新行(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
    
    • 1

    搜索文件 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
    
    • 1

    将输出以下三行:

    Harley is smart
    Harley
    I like Harley

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

    将输出以下两行:

    Harley is smart
    Harley

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

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

    将输出以下两行:

    Harley
    I like Harley

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

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

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

    Harley

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

    匹配单词:\<\>

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

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

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

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

    grep 'H[aA]' data.txt
    
    • 1

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

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

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

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

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

    grep 'H[^aA]' data.txt
    
    • 1

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

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

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

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

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

    重复运算符:*+?

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

    限定运算符:{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 个数字
    
    • 1
    • 2
    • 3
    • 4

    组(())和或(|

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

    cat dog bird hamster

    可以使用如下命令:

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

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

    通配符

    每当键入以文件名作为参数的命令时,可以通过使用特定的元字符 —— 通配符 来指定多个文件。术语 元字符 就是由 shell 解释时拥有特殊含义的字符。当在文件名中使用通配符时,通配符就拥有特殊的含义。

    ls h*		#列举当前工作目录中的所有以字母 ‘h’ 开头的文件
    
    • 1

    咋一看,通配符与正则表达式的元字符极其相似。实际上,通配符更加简单一些。此外,它们只有一个用途:当键入一条命令时匹配一组文件名。正则表达式中的预定义字符类也适用于通配符。以下为基本通配符极其含义:

    符号含义
    *匹配 0 个或多个字符构成的序列
    ?匹配任何单个字符
    [list]匹配 list 中的任何字符(定义字符集合)
    [^list]匹配不在 list 中的任何字符
    {string1,string2,…}依次匹配每个字符串 (注意逗号前后不能有空格)

    比如:

    • d?:以 d 开头的两个字符的文件名
    • ?*y:至少两个字符,并且以 y 结尾的文件名
    • test.[co]:test.c 或 test.o
    • ls [^Hh]*:显示工作目录中所有不以字母 H 或 h 开头的文件名
    • [a-z]*:以小写字母开头的文件名
    • ls /home/{abc,xyz,123}:分别列举 /home/abc、/home/xyz、/home/123 中所有文件的名称
    • mkdir ~/work/{abc,xyz,123}:在 /home/work/ 目录下创建三个文件夹,分别是 abc、xyz、123






    读后有收获,资助博主养娃 - 千金难买知识,但可以买好多奶粉 (〃‘▽’〃)
    千金难买知识,但可以买好多奶粉

  • 相关阅读:
    数字孪生技术栈的应用场景的优点
    (课程笔记)C++后端知识点大纲
    APP性能测试指标
    AWS 中文入门开发教学 25- 高可用性设计 - 建立 ALB 负载均衡
    说话人识别声纹识别CAM++,ECAPA-TDNN等算法
    Maven 安装配置
    深度解读《深度探索C++对象模型》之拷贝构造函数
    【Java】ArrayList集合存入学生对象
    JAVA知识点笔记
    C# OpenVINO 通用OCR识别 文字识别 中文识别 服务
  • 原文地址:https://blog.csdn.net/zhzht19861011/article/details/133962915