Linux之正则表达式---grep、元字符、任意字符、锚、中括号、否定、POSIX字符类

2023-05-16

正则表达式是一个非常重要的用于文本操作的工具。

0.参考文献

《Linux命令行大全》 [美] William E. Shotts. Jr 著 郭光伟 郝记生 译, 人民邮电出版社

更多有用的Linux知识详解,可参加博主的Linux学习导航页

1.什么是正则表达式

正则表达式是一种符号表示法,用于识别文本模式。在某种程度上,它们类似于匹配文件和路径名使用的shell通配符
许多命令行工具和大多数编程语言都支持正则表达式,以此来解决文本操作方面的问题。但不同的编程语言之间,正则表达式会略有不同。
方便起见,我们将正则表达式的讨论限定在POSIX标准中。

2. grep–文本搜索

处理正则表达式的主要程序是grep。grep程序名字源于"global regular expression print"。实际上,grep搜索文本中与指定正则表达式匹配的行,并将结果送至标准输出。
grep程序的语法为

grep [options] regex [file ...]

表1 grep常用的选项

选项功能描述
-i忽略大小写。也可以用–ignore-case指定
-v不匹配。正常情况下,grep会输出匹配行,而该选项可使grep输出不包含匹配项的所有行,也可以用–invert-match指定。
-c输出匹配项数目(如果有-v选项,就输出不匹配项的数目)而不是直接输出匹配行自身,也可使用–count指定
-l输出匹配项文件名而不是直接输出匹配行自身。也可以用–files-with-matches指定
-L与-l选项类似,但输出的是不含匹配项的文件名,可以用–files-without-match指定
-n在每个匹配行前面加上该行在文件内的行号。也可以用–line-number指定
-h进行多文件搜索时,抑制文件名输出。也可用–no-filename指定

我们创建几个示例文件来进行搜索

$ ls /bin > dirlist-bin.txt
$ ls /usr/bin > dirlist-usr-bin.txt
$ ls /sbin/ > dirlist-sbin.txt
$ ls /usr/sbin > dirlist-usr-sbin.txt
$ ls dirlist*.txt
dirlist-bin.txt  dirlist-sbin.txt  dirlist-usr-bin.txt  dirlist-usr-sbin.txt

我们可以对文件列表执行简单的搜索

$ grep bzip dirlist*.txt
dirlist-bin.txt:bzip2
dirlist-bin.txt:bzip2recover

上个例子中,grep命令会搜索所有的文件,以查找字符串bzip,并找到了两个匹配项,并且这两个匹配项都在文件dirlist-bin.txt中。
如果我们只对包含匹配项的文件感兴趣而不是对匹配项本身感兴趣,可以指定-l选项。

$ grep -l bzip dirlist*.txt
dirlist-bin.txt

相反,如果只想查看那些不包含匹配项的文件,则可以用如下命令行

$ grep -L bzip dirlist*.txt
dirlist-sbin.txt
dirlist-usr-bin.txt
dirlist-usr-sbin.txt

3.元字符和文字

字符串bzip中的字符都是文字字符(literal character),即它们只能与自身进行匹配。除了文字字符,正则表达式还可以包含用于指定更为复杂的匹配的元字符。正则表达式的元字符包含以下字符

^ $ . [ ] { } - ? * + ( ) | \

4.任意字符

接下来要讨论的第一个元字符是**“点”字符或者句点字符。该字符用于匹配任意字符**。

$ grep -h '.zip' dirlist*.txt
bunzip2
bzip2
bzip2recover
gunzip
gzip
funzip
gpg-zip
unzip
unzipsfx

上述命令行,搜索到所有匹配正则表达式.zip的命令行。但其输出中没有包含zip程序,这是因为正则表达式中的“.”元字符将匹配长度增加到了4个字符。而“zip”只包含3个字符。此时,文件扩展名中的“.”符号也被当做**“任意字符”**处理了。

5.锚

插入符(^)和美元符号($)在正则表达式中被当做,也就是说正则表达式只与行的开头(^)或是末尾($)的内容进行匹配比较

$ grep -h '^zip' dirlist*.txt
zipdetails
zipgrep
zipinfo
$ grep -h 'zip$' dirlist*.txt
gunzip
gzip
funzip
gpg-zip
unzip
$ grep -h '^zip$' dirlist*.txt
zip

6.中括号表达式和字符类

中括号除了可以用于匹配正则表达式中给定位置的任意字符外,还可以用于匹配指定字符集的单个字符
如下命令行则利用一个两个字母组成的字符集,用于匹配包含bzip和gzip字符串的文本行。

$ grep -h '[bg]zip' dirlist*.txt
bzip2
bzip2recover
gzip

一个字符集可以包含任意数目的字符,并且当元字符放置到中括号时,会失去它们的特殊意义
两种情况下,在中括号中使用元字符,会有不同的意义。第一个是插入符(^),其在中括号中表示否定。另外一个是连字符(-),它表示字符范围。

6.1 否定

如果中括号内的第一个字符是插入符(^),那么剩下的字符则被当做不应该在指定位置出现的字符集。

$ grep -h '[^bg]zip' dirlist*.txt
bunzip2
gunzip
funzip
gpg-zip
unzip
unzipsfx

以上例子通过否定操作,得到那些包含zip字符串但zip前面既不是b也不是g的所有程序。注意,此时zip仍没有出现在结果列表中,可见否定时,字符集仍然需要在指定位置有对应字符。
只有在插入字符(^)在中括号表达式中第一个字符时才会被当做否定符。如果不是,则被转义为普通字符。

6.2 传统字符范围

如果我们希望查找文件名义大写字母开头的文件,可以用以下简单方法:

$ grep -h '^[A-Z]' dirlist*.txt
MAKEDEV
ControlPanel
Mail
NF
VGAuthService
X
X11
Xorg

再例如,下面例子可以匹配以字母和数字开头的所有文件名

$ grep -h '^[A-Za-z0-9]' dirlist*.txt

如果我们真要查找含有连字符“-”的文件,可以在中括号中第一个字符使用连字符

$ grep -h '[-AZ]' dirlist*.txt

6.3 POSIX字符类

表2 POSIX字符类

字符类描述
[:alnum:]字母字符和数字字符;在ASCII码中,与[A-Za-z0-9]等效
[:word:]基本与[:alnum:]一样,只是多了个下划线字符(_)
[:alpha:]字母字符
[:blank:]包括空格和制表符
[:cntrl:]ASCII控制码;包含ASCII字符0~31以及127
[:digit:]数字0~9
[:graph:]可见字符;在ASCII中,包含字符33~126
[:lower:]小写字母
[:punct:]标点符号字符
[:print:]可打印字符;包括[:graph:]中所有字符再加上空格字符
[:space:]空白字符如空格符、制表符、回车符、换行符、垂直制表符以及换页符
[:upper:]大写字母
[:xdigit:]用于表示十六进制的字符

7. POSIX基本正则表达式和扩展正则表达式

POSIX规范将正则表达式分为两种:基本正则表达式(BRE)扩展正则表达式(ERE)
BRE和ERE的不同仅仅在于元字符的不同。在BRE方式中,只承认^、$、.、[、]、*这些元字符,所有的其它字符都被识别为文字字符。而ERE中,则添加了(、)、{、}、?、+、|等元字符。
由于下面要讨论的特性是ERE的一部分,所以需要使用不一样的grep。一般是执行egrep程序,但是GNU版本的grep可以运行-E选项以支持ERE方式。

8.或选项

括号表达式可以从指定字符集中匹配单一字符,而或选项则用于从字符集或正则表达式集中寻找匹配项

x$ echo "AAA" | grep AAA
AAA
$ echo "AAA" | grep BBB
$ echo "AAA" | grep -E 'AAA|BBB'
AAA

这里出现了’AAA|BBB’正则表达式,含义是“匹配字符串AAA或者字符串BBB”。
注意,此时使用扩展选项,因此需要为grep增加-E选项,并且将正则表达式引起来防止shell将元字符“|”当做管道处理。
另外,或选项不局限于两种,例如

$ echo "AAA" | grep -E 'AAA|BBB|CCC'
AAA

为了将或选项与其它正则表达式符号结合使用,可以用“()”将或选项的所有元素与其它符号隔开。

$ grep -Eh '^(bz|gz|zip)' dirlist*.txt

以上表达式的含义是匹配文件名义bz、gz或是zip开头的文件。如果不含有括号

$ grep -Eh '^bz|gz|zip' dirlist*.txt

含义就变成了以bz开头或者是包含gz和zip的文件。

9.限定符

扩展正则表达式(ERE)提供多种方法指定某元素匹配的次数

9.1 ?—匹配某元素0次或1次

该限定符实际上意味着“前面的元素可选”。
例如检查某电话号的有效性,必须是下面格式(nnn) nnn-nnnn和nnn nnn-nnnn中的一种,其中n是数值。
可以构造下面的正则表达式:
^(?[0-9][0-9][0-9])? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$
表示括号字符只能匹配一次或零次。反斜杠告诉shell括号已经转义。

$ echo "(555) 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'
(555) 123-4567
$ echo "555 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'
555 123-4567
$ echo "AAA 123-4567" | grep -E '^\(?[0-9][0-9][0-9]\)? [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]$'

9.2 *—匹配某元素多次或零次

与“?”元字符类似,“*”用于表示一个可选择的条目。然而,与“?”不同,该条目可以出现多次,而不仅仅是一次。
例如,我们想知道一串字符是否以大写字母开头而以句号结束,并且中间内容是任意数目的大小写字母和空格。那么可以使用如下正则表达式。
[[:upper:]][[:upper:][:lower:] ]*.
以上表达式包含了三个条目:包含[:upper:]字符类的中括号表达式、包含[:upper:]和[:lower:]两个字符类以及一个空格的空括号表达式、用反斜杠转义过的圆点字符。第二个条目中紧跟“*”元字符,所以只要句子的第一个字母是大写字母,后面不管会出现多少数目的大小写字母都无关紧要。

$ echo "This works." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'
This works.
$ echo "This Works." | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'
This Works.
$ echo "this does not" | grep -E '[[:upper:]][[:upper:][:lower:] ]*\.'

9.3 ±–匹配某元素一次或多次

'+‘元字符与’*‘非常类似,只是’+'要求置于其前面的元素至少出现一次
示例如下,该正则表达式用于匹配由单个空格分隔的一个或者多个字母字符组成的行。
^([[:alpha:]]+ ?)+$

$ echo "This that" | grep -E '^([[:alpha:]]+ ?)+$'
This that
$ echo "a b c" | grep -E '^([[:alpha:]]+ ?)+$'
a b c
$ echo "a b 9" | grep -E '^([[:alpha:]]+ ?)+$'

$echo "a b  d" | grep -E '^([[:alpha:]]+ ?)+$'

9.4 {}—以指定次数匹配某元素

“{”和“}”元字符用于描述最小和最大匹配次数的需求。有四种方法
表3 指定匹配次数

指定项含义
{n}前面的元素恰好出现n次则匹配
{n,m}前面的元素出现次数在n~m次之间时则匹配
{n,}前面的元素出现次数超过n次则匹配
{,m}前面的元素出现次数不超过m次则匹配

例如前面电话号码可以改为
“^(?[0-9]{3})? [0-9]{3}-[0-9]{4}$”

10.正则表达式的应用

10.1 使用grep

以上已经展示很多了

10.2 用find查找文件名

find命令的test选项可以用正则表达式表示,与grep有所不同,grep命令是搜索那些只包含与指定表达式匹配的字符串的行,而find则要求文件名与指定表达式完全一致
例如

$ find . -regex '.*[^-_-./0-9a-zA-Z].*'

10.3 用locate查找文件

locate命令既支持基本正则表达式(–regexp)选项,也支持扩展正则表达式(–regex选项)。利用locate,可以完成之前对dirlist文件所做的许多操作。

$  locate --regex 'bin/(z|gz|zip)'

10.4 利用less和vim命令搜索文本

less和vim采用同样的方式进行文本搜索。按下“/”键后输入正则表达式,即开始进行搜索。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux之正则表达式---grep、元字符、任意字符、锚、中括号、否定、POSIX字符类 的相关文章

随机推荐

  • Linux进程详解(非常详细且入门)---ps、top、kill、fg

    常见的操作系统都支持多重任务处理 multitasking 系统通过快速切换运行中的程序来实现多任务的同时执行 Linux内核通过使用进程来管理多重任务 进程是Linux用来安排不同程序等待CPU调度的一种组织方式 1 进程如何工作 系统启
  • Linux环境详情与配置——export,alias,set,printenv

    在shell会话调用环境 environment 期间 shell会存储大量的信息 程序使用存储在环境中的数据来确定我们的配置 1 环境中存储的是什么 shell在环境中存储了两种基本类型的数据 环境变量 environment varia
  • Linux之vi介绍----完整入门及快捷键

    0 前言 自从我的学习linux笔记开始更新后 xff0c 阅读量挺高 xff0c 说明大家使用linux热情很高 在前边几篇博客中我未指明参考书籍 xff0c 这里做下说明 xff0c 将慢慢补充之前几篇的参考说明 我的博客源于对以下书本
  • Linux系统软件包管理——dpkg、apt-get、rpm、yum

    软件包管理是一种在系统上安装 维护软件的方法 主要有两种方式 xff0c 一种是通过安装Linux经销商发布的软件包来满足软件需求 xff1b 一种是先下载源代码 xff0c 然后对其进行编译 xff08 博主在使用jetson tx2时
  • Linux之网络相关命令——ping、tranceroute、netstat、ftp、lftp、wget、ssh、scp、sftp

    网络连接方面 xff0c Linux可以说是万能的 Linux工具可以建立各种网络系统及应用 xff0c 包括防火墙 路由器 域名服务器 NAS xff08 网络附加存储 xff09 盒等 这里主要讲一些经常用到的命令 xff0c 涉及网络
  • Linux文件搜索命令介绍——locate、find、xargs、touch、stat

    本文主要介绍两个用在Linux系统中搜索文件的工具 locate 通过文件名查找文件find 在文件系统目录框架中查找文件 同时 xff0c 我们也会介绍一个通常与文件搜索命令一起使用 处理搜索结果文件列表的命令 xargs 从标准输入中建
  • ubuntu使用bash脚本+gnome实现开机自启python程序和崩溃重启

    这里以tx2的ubuntu18 04为例 xff0c 对ubuntu系统是有效的 例如我们要实现开机自动启动 home me test main py程序 xff0c 并且当main py出现任何意料之外的错误报错时 xff0c 系统可以重
  • http请求转串口通信系统开发者文档

    http请求转串口通信系统介绍 系统价值和功能与口号 让所有单片机联网通信 1 系统使用c语言mqtt协议开发esp8266为硬件载体 xff0c 调用者只需要任意编程语言的串口通信即可 xff01 2 是一个好用的免费的稳定的单片机网络通
  • ubuntu实现屏幕的旋转和开启自动旋转屏幕

    1 旋转屏幕 有两种方法 xff0c 一种是命令行 xff0c 一种是图形界面 这里只介绍命令行 xff0c 因为其简单 xrandr o left 向左旋转90度 xff0c 用于横屏转竖屏 xrandr o right 向右旋转90度
  • MaskRCNN在Jetson tx2上的测速结果

    博主测试了在不同模式 精度下降MaskRCNN部署到Jetson TX2上的测速结果 xff0c 与大家分享讨论 对FasterRCNN的测速可见FasterRcnn在Jetson TX2上测速 使用的MaskRCNN框架 matterpo
  • FasterRcnn在Jetson TX2上测速

    博主测试了在不同模式 精度下将FasterRCNN部署到Jetson TX2上的测速结果 xff0c 与大家分享讨论 对于MaskRCNN的部署结果可参见 MaskRCNN在Jetson tx2上的测速结果 使用的Caffe版本Faster
  • Linux学习笔记导航页

    本博客中与博主Linux学习相关的博文导航 xff0c 方便查看 Linux系统ls命令详解Linux系统中目录的内容详解 bin dev etc home lib opt usr varLinux操作文件与目录 cp mv mkdir r
  • Jetson TX2使用经验导航页

    本博客中与Jetson TX2使用相关的博文导航 xff0c 方便查看 JetsonTX2 之刷机 Jetpack 4 3TX2 ubuntu 18 04 更换清华镜像源Jetson TX2刷机后查看CUDA和CUDNN版本 以JetPac
  • Pytorch学习导航页

    本博客中与pytorch学习相关的博文 xff0c 方便查看 Pytorch源码学习之一 xff1a torchvision models alexnetPytorch源码学习之二 xff1a torchvision models vggP
  • Python小技巧导航页

    本博客中与Python使用技巧相关的博文 xff0c 方便查看 使用matplotlib绘图库的pyplot快速绘图Python调用face 43 43 API完成本地图片的人脸检测Python爬虫 按照关键词爬取视觉中国高清图像pytho
  • Linux归档与备份——gzip、gunzip、bzip2、bunzip2、tar、zip、unzip、rsync

    维护系统数据安全是计算机系统管理者的基本任务之一 xff0c 及时创建系统文件的备份文件是维度系统数据安全的一种常用方法 本节主要介绍以下命令 文件压缩程序 gzip 压缩和解压缩文件工具bzip2 块排序文件压缩工具 文件归档程序 tar
  • Linux之存储介质——mount、umount、fdisk、mkfs

    本节讨论设备级别的数据处理 对于诸如硬盘之类的物理存储器 网络存储器以及像RAID 独立冗余磁盘陈列 和LVM 逻辑卷管理 之类的虚拟存储器 xff0c Linux都有惊人的处理能力 本节主要用到以下命令 mount 挂载文件系统umoun
  • Jetson TX2挂载SD卡--亲测有效!

    不得不说 xff0c TX2用于深度学习算法的部署 xff0c 一个很大的问题是硬盘容量太小 xff0c 由于我的应用需求需要存储大量数据 xff0c 因此需要挂载一个SD卡 关于Linux挂载存储介质相关原理可参考我的博客 Linux之存
  • 实用的测试流程梳理总结(质量保障)

    废话不多说 xff0c 简明扼要的列出我认为测试最重要的几点 xff1a 1 测试思维 xff1a 优秀的测试思维对case设计的好坏起决定作用 xff0c case的好坏对测试效率和测试质量起决定作用 xff0c 所以测试思维非常重要 我
  • Linux之正则表达式---grep、元字符、任意字符、锚、中括号、否定、POSIX字符类

    正则表达式是一个非常重要的用于文本操作的工具 0 参考文献 Linux命令行大全 美 William E Shotts Jr 著 郭光伟 郝记生 译 xff0c 人民邮电出版社 更多有用的Linux知识详解 xff0c 可参加博主的Linu