【Linux命令行与Shell脚本编程】第十九章 正则表达式

Linux命令行与Shell脚本编程 第十九章 正则表达式


文章目录

  • Linux命令行与Shell脚本编程 第十九章 正则表达式
  • 九.正则表达式
    • 9.1.正则表达式基础
      • 9.1.1.正则表达式的类型
      • 9.2.定义BRE模式
        • 9.2.1.普通文本
        • 9.2.2.特殊字符
      • 9.2.3.锚点字符
        • 锚定行首^
        • 锚定行尾$
        • 组合锚点
      • 9.2.4.点号字符\.
      • 9.2.5.字符组[]
      • 9.2.6.排除字符组
      • 8.2.7.区间
      • 9.2.8.特殊字符组
      • 9.2.9.星号*
    • 9.3.扩展正则表达式
      • 9.3.1.问号?
      • 9.3.2.加号+
      • 9.3.3.花括号\{\}
      • 9.3.4.竖线符号\|
      • 9.3.5.表达式分组
    • 9.4.实战
      • 9.4.1.目录文件计数


九.正则表达式

  • 正则表达式基础
  • 定义BRE模式
  • 扩展正则表达式

在sed和gawk中创建正则表达式,以得到所需的数据。

9.1.正则表达式基础

正则表达式是一种可供Linux工具过滤文本的自定义模板,使用元字符来描述数据流中的一个或多个字符.
Linux工具(比如sed或gawk)会在读取数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进行处理。
正则表达式包含文本和/或特殊字符.

9.1.1.正则表达式的类型

不同的应用程序可能使用不同类型的正则表达式。
编程语言(Java、Python)、Linux工具(sed、gawk和grep)以及主流应用程序(MySQL数据库服务器)。

正则表达式由正则表达式引擎实现。这种底层软件,负责解释正则表达式并用这些模式进行文本匹配。

Linux 中流行的两种:

  • POSIX基础正则表达式(basic regular expression,BRE)引擎。
  • POSIX扩展正则表达式(extended regular expression,ERE)引擎。

大多数Linux工具至少符合POSIX BRE引擎规范。但有些工具(比如sed)仅符合BRE引擎规范的一个子集。
(出于速度方面的考虑导致,sed希望尽可能快地处理数据流中的文本)

POSIX ERE引擎多见于依赖正则表达式过滤文本的编程语言中。为常见模式(比如数字、单词以及字母或数字字符)提供了高级模式符号和特殊符号。
gawk就是使用ERE引擎来处理正则表达式。

9.2.定义BRE模式

最基本的BRE模式是匹配数据流中的文本字符.

9.2.1.普通文本

正则表达式对大小写敏感.
正则表达式并不关心模式在数据流中出现的位置,也不在意模式出现了多少次。
只要能匹配文本字符串中任意位置的模式,正则表达式就会将该字符串传回Linux工具。

在正则表达式中,空格和其他的字符没有区别.如果在正则表达式中定义了空格,那么必须出现在数据流中。甚至可以创建匹配多个连续空格的正则表达式.

$ cat data1
This is a normal line of text.
This is  a line with too many spaces.
$ sed -n '/  /p' data1
This is  a line with too many spaces.

9.2.2.特殊字符

正则表达式中的一些字符具有特别的含义:

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

不能在匹配普通文本的模式中单独使用这些字符.
如果要将某个特殊字符视为普通字符,则必须将其转义.使用特殊转移字符反斜线(\)。

尽管正斜线 / 不属于正则表达式的特殊字符,但如果出现在sed或gawk的正则表达式中,就会出现错误,所以正斜线也需要进行转义.

9.2.3.锚点字符

默认情况下,当指定一个正则表达式模式时,只要模式出现在数据流中的任何地方,它就能匹配.有两个特殊字符可以用来将模式锁定在数据流中的行首或行尾。

锚定行首^

脱字符(^)可以指定位于数据流中文本行行首的模式。如果模式出现在行首之外的位置,则正则表达式无法匹配。
使用脱字符,就必须将其置于正则表达式之前

$ echo "The book store" | sed -n '/^book/p'
$
$ echo "Books are great" | sed -n '/^Book/p'
Books are great

如果将脱字符放到正则表达式开头之外的位置,那么就跟普通字符一样,没有特殊含义

$ echo "This ^ is a test" | sed -n '/s ^/p'
This ^ is a test

如果正则表达式模式中只有脱字符,就不必用反斜线来转义。但如果在正则表达式中先指定脱字符,随后还有其他文本,就必须在脱字符前用转义字符.

$ echo "This is ^ a test" | sed -n '/^ a test/p'
$ echo "This is ^ a test" | sed -n '/\^ a test/p'
This is ^ a test

锚定行尾$

与在行首查找模式相反的情况是在行尾查找。特殊字符美元符号($)定义了行尾锚点。将这个特殊字符放在正则表达式之后则表示数据行必须以该模式结尾.

$ echo "This is a good book" | sed -n '/book$/p'
This is a good book

组合锚点

组合使用行首锚点和行尾锚点。

$ cat data4
this is a test of using both anchors
I said this is a test
this is a test
I'm sure this is a test.
$ sed -n '/^this is a test$/p' data4
this is a test

将这两个锚点直接组合,之间不加任何文本,可以过滤掉数据流中的空行。
组合 删除命令d就可以删除掉文本中的空行.

$ cat data5
This is one test line.This is another test line.
$ sed '/^$/d' data5
This is one test line.
This is another test line.

9.2.4.点号字符.

点号字符可以匹配除换行符之外的任意单个字符。(空格也是字符,可以匹配)
点号字符必须匹配一个字符,如果在点号字符的位置没有可匹配的字符,那么模式不成立。

$ cat data6
This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.
at ten o'clock we'll go home.
$ sed -n '/.at/p' data6
The cat is sleeping.
That is a very nice hat.
This test is at line four.

9.2.5.字符组[]

想要限定要匹配的具体字符使用字符组.
可以在正则表达式中定义用来匹配某个位置的一组字符。如果字符组中的某个字符出现在了数据流中,那就能匹配该模式。

方括号 [] 用于定义字符组。
在不太确定某个字符的大小写时非常适合使用字符组.

$ echo "Yes" | sed -n '/[Yy]es/p'
Yes
$ echo "yes" | sed -n '/[Yy]es/p'
yes

在一个正则表达式中可以使用多个字符组.
可以将多个字符组组合在一起,以检查数字是否具备正确的格式.

$ cat data8
60633
46201
223001
4353
22203
$ sed -n '
> /^[0123456789][0123456789][0123456789][0123456789][0123456789]$/p
> ' data8
60633
46201
22203

9.2.6.排除字符组

在正则表达式中,可以反转字符组的作用:匹配字符组中没有的字符。在字符组的开头添加脱字符^:

$ sed -n '/[^ch]at/p' data6
This test is at line four.

即使是排除型,字符组仍必须匹配一个字符,以at为起始的行还是不能匹配模式!!!

8.2.7.区间

可以用单连字符在字符组中表示字符区间。只需指定区间的第一个字符、连字符以及区间的最后一个字符。
根据Linux系统使用的字符集,字符组会包括在此区间内的任意字符。

$ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data8
60633
46201
45902

同样的方法也适用于字母:

$ sed -n '/[c-h]at/p' data6
The cat is sleeping.
That is a very nice hat.

可以在单个字符组内指定多个不连续的区间:

$ sed -n '/[a-ch-m]at/p' data6
The cat is sleeping.
That is a very nice hat.

9.2.8.特殊字符组

BRE还提供了一些特殊的字符组,用来匹配特定类型的字符。

字符组描述
[[:alpha:]]匹配任意字母字符,无论大小写
[[:alnum:]]匹配任意字母和数组字符,0-9、a-z、A-Z
[[:blank:]]匹配空格和制表符
[[:digit:]]匹配0-9的数字
[[:lower:]]匹配a-z的字母
[[:upper:]]匹配A-Z的字母
[[:print:]]匹配任意可打印字符
[[:punct:]]匹配标点符号
[[:space:]]匹配任意空白字符:空格、制表符、换行符、分页符、垂直制表符、回车符

特殊字符组在正则表达式中的用法和普通字符组一样:

$ echo "abc" | sed -n '/[[:digit:]]/p'
$ echo "abc" | sed -n '/[[:alpha:]]/p'
abc
$ echo "abc123" | sed -n '/[[:digit:]]/p'
abc123
$ echo "This is a test" | sed -n '/[[:punct:]]/p'
$ echo "This is, a test" | sed -n '/[[:punct:]]/p'
This is, a test

9.2.9.星号*

在字符后面放置星号,表明该字符必须在匹配模式的文本中出现0次或多次.

$ echo "ik" | sed -n '/ie*k/p'
ik
$ echo "iek" | sed -n '/ie*k/p'
iek
$ echo "ieek" | sed -n '/ie*k/p'
ieek
$ echo "ieeek" | sed -n '/ie*k/p'
ieeek
$ echo "ieeeek" | sed -n '/ie*k/p'
ieeeek

某些单词在英美中不同,借助 星号可以匹配:

$ echo "I'm getting a color TV" | sed -n '/colou*r/p'
I'm getting a color TV
$ echo "I'm getting a colour TV" | sed -n '/colou*r/p'
I'm getting a colour TV
$

将点号字符和星号字符组合起来。这个组合能够匹配任意数量的任意字符:

$ echo "this is a regular pattern expression" | sed -n '
> /regular.*expression/p'
this is a regular pattern expression

星号用于字符组时,指定可能在文本中出现0次或多次的字符组或字符区间:

$ echo "bt" | sed -n '/b[ae]*t/p'
bt
baaeeet
$ echo "baeeaeeat" | sed -n '/b[ae]*t/p'
baeeaeeat
$ echo "baakeeet" | sed -n '/b[ae]*t/p'

9.3.扩展正则表达式

POSIX ERE模式提供了一些可供Linux应用程序和工具使用的额外符号。gawk支持ERE模式,sed不支持。

可用于gawk脚本中的常见ERE模式符号。

9.3.1.问号?

问号表明字符可以出现0次或1次,不会匹配多次出现的该字符.用法与星号类似,可以作用与字符组.

$ echo "bt" | gawk '/be?t/{print $0}'
bt
$ echo "bet" | gawk '/be?t/{print $0}'
bet
$ echo "beet" | gawk '/be?t/{print $0}'

9.3.2.加号+

加号表明前面的字符可以出现1次或多次,必须至少出现1次。用法与星号类似,可以作用与字符组.

$ echo "bt" | gawk '/b[ae]+t/{print $0}'
$
$ echo "bat" | gawk '/b[ae]+t/{print $0}'
bat
$ echo "bet" | gawk '/b[ae]+t/{print $0}'
bet
$ echo "beat" | gawk '/b[ae]+t/{print $0}'
beat
$ echo "beet" | gawk '/b[ae]+t/{print $0}'
beet
$ echo "beeat" | gawk '/b[ae]+t/{print $0}'
beeat

9.3.3.花括号{}

ERE中的花括号允许为正则表达式指定具体的可重复次数,称为区间。

可以用两种格式来指定区间:

  • m:正则表达式恰好出现m次。
  • m, n:正则表达式至少出现m次,至多出现n次。

默认情况下,gawk也不识别正则表达式区间,必须指定gawk的命令行选项–re-interval。

$ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'
$
$ echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1}t/{print $0}'
$
$ echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}'
$
$ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
beet
$ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'
$
$ echo "bt" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
$
$ echo "beet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
beet
$ echo "beeat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
$

9.3.4.竖线符号|

竖线符号允许在检查数据流时,以逻辑OR方式指定正则表达式引擎要使用的两个或多个模式。任何一个模式匹配了数据流文本,就视为匹配。
竖线符号两侧的子表达式可以采用正则表达式可用的任何模式符号(包括字符组)

$ echo "The cat is asleep" | gawk '/cat|dog/{print $0}'
The cat is asleep
$ echo "The dog is asleep" | gawk '/cat|dog/{print $0}'
The dog is asleep
$ echo "The sheep is asleep" | gawk '/cat|dog/{print $0}'

9.3.5.表达式分组

用圆括号对正则表达式进行分组。分组之后,每一组会被视为一个整体,可以像对普通字符一样对该组应用特殊字符。

$ echo "Sat" | gawk '/Sat(urday)+/{print $0}'
$ echo "Saturday" | gawk '/Sat(urday)+/{print $0}'
Saturday

将分组和竖线符号结合起来创建可选的模式匹配组:

$ echo "cat" | gawk '/(c|b)a(b|t)/{print $0}'
cat
$ echo "cab" | gawk '/(c|b)a(b|t)/{print $0}'
cab
$ echo "bat" | gawk '/(c|b)a(b|t)/{print $0}'
bat
$ echo "bab" | gawk '/(c|b)a(b|t)/{print $0}'
bab
$ echo "tab" | gawk '/(c|b)a(b|t)/{print $0}'
$

9.4.实战

9.4.1.目录文件计数

对PATH环境变量中各个目录所包含的文件数量进行统计.

PATH中的各个路径由冒号分隔。要获取可在脚本中使用的目录列表,须用空格替换冒号.

$ echo $PATH | sed 's/:/ /g'
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin
/usr/games /usr/local/games

分离出目录之后,可以使用标准for语句遍历每个目录:

mypath=`echo $PATH | sed 's/:/ /g'`
for directory in $mypath
do
...
done

对于单个目录,可以用ls命令列出其中的文件,再用另一个for语句来遍历每个文件,对文件计数器增值。

$ cat countfiles
#!/bin/bash
# count number of files in your PATH
mypath=$(echo $PATH | sed 's/:/ /g')
count=0
for directory in $mypath
docheck=$(ls $directory)for item in $checkdocount=$[ $count + 1 ]doneecho "$directory - $count"count=0
done
$ ./countfiles /usr/local/sbin - 0
/usr/local/bin - 2
/usr/sbin - 213
/usr/bin - 1427
...
/usr/local/games - 0

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/67780.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spring专题】Spring之Bean的生命周期源码解析——阶段二(IOC之实例化)

目录 前言阅读准备阅读指引阅读建议 课程内容一、SpringIOC之实例化1.1 简单回顾1.2 概念回顾1.3 核心方法讲解 二、方法讲解2.1 AbstractBeanFactory#getMergedLocalBeanDefinition:合并BeanDefinition2.2 AbstractAutowireCapableBeanFactory#createBean&#xff…

USB协议精读

1.1.枚举 1.1.1.上电连接过程 1.1.2.设备识别过程 1.1.3.枚举过程 1.1.3.1.获取设备描述符(只关注设备描述符中最大数据包长度) 1.1.3.2.设置设备针对主机的唯一从机地址 1.1.3.3.获取完整设备描述符 1.1.3.4.获取配置描述符 先获取标准配置描述符&a…

【数据库基础】Mysql下载安装及配置

下载 下载地址:https://downloads.mysql.com/archives/community/ 当前最新版本为 8.0版本,可以在Product Version中选择指定版本,在Operating System中选择安装平台,如下 安装 MySQL安装文件分两种 .msi和.zip [外链图片转存失…

JVM运行时五大数据区域详解

前言: java虚拟机再执行Java程序的时候把它所拥有的内存区域划分了若干个数据区域。这些区域有着不同的功能,各司其职。这些区域不但功能不同,创建、销毁时间也不同。有些区域为线程私有,如:每个线程都有自己的程序计数…

openGauss学习笔记-39 openGauss 高级数据管理-分区表

文章目录 openGauss学习笔记-39 openGauss 高级数据管理-分区表39.1 范围分区表的分类39.2 创建范围分区39.2.1 创建VALUES LESS THAN范围分区表语法格式39.2.2 创建VALUES LESS THAN范围分区表参数说明39.2.3 创建VALUES LESS THAN范围分区表示例 39.3 询分区表39.3.1 查询分区…

【JPCS出版】第五届能源、电力与电网国际学术会议(ICEPG 2023)

第五届能源、电力与电网国际学术会议(ICEPG 2023) 2023 5th International Conference on Energy, Power and Grid 最近几年,不少代表委员把目光投向能源电力领域,对促进新能源发电产业健康发展、电力绿色低碳发展,提…

基于Yolov5与LabelMe训练自己数据的图像分割完整流程

基于Yolov5与LabelMe训练自己数据的实例分割完整流程 1. Yolov5配置2. 创建labelme虚拟环境4. 接下来开始使用labelme绘制分割数据集4.1 json to txt4.2 划分数据集(可分可不分) 5. 训练 1. Yolov5配置 参照这边文章: https://blog.csdn.net/ruotianxia/article/de…

常见分辨率时序信息

分辨率列表 分辨率一:640x480(逐行) 分辨率二:800x600(逐行) 分辨率三:1024x768(逐行) 分辨率四:大名鼎鼎720P(逐行) 注:选择720P@30帧的,需拉长HOR TOTAL TIME 分辨率五:1280x800(逐行) 分辨率六:1280x960(逐行

Nginx网站服务(安装nginx、平滑升级nginx、nginx各种访问配置)

一、Nginx概述 1、什么是nginx? 稳定性高、系统资源消耗低、对HTTP并发连接的处理能力高(单台物理器可支持30000-50000个并发请求) NG并发连接能力有2个因素的影响 ①CPU的个数 ②本地吴立琪系统的最大文件打开数2、Nginx应用场景 静态服…

学习笔记整理-JS-04-流程控制语句

文章目录 一、条件语句1. if语句的基本使用2. if else if多条件分支3. if语句算法题4. switch语句5. 三元运算符 二、循环语句1. for循环语句2. for循环算法题3. while循环语句4. break和continue5. do while语句 三、初识算法1. 什么是算法2. 累加器和累乘器3. 穷举法4. 综合算…

uni-app中使用pinia

目录 Pinia 是什么? uni-app 使用Pinia main.js 中引用pinia 创建和注册模块 定义pinia方式 选项options方式 定义pinia 页面中使用 pinia选项options方式 函数方式 定义pinia 页面中使用 函数方式 定义的pinia Pinia 是什么? Pinia&#xff0…

软件测试基础篇——MySQL

MySQL 1、数据库技术概述 数据库database:存放和管理各种数据的仓库,操作的对象主要是【数据data】,科学的组织和存储数据,高效的获取和处理数据SQL:结构化查询语言,专为**关系型数据库而建立的操作语言&…