bash shell 无法使用 perl 正则

哈喽大家好,我是咸鱼。今天跟大家分享一个关于正则表达式的案例,希望能够对你有所帮助
案例现象
前几天有一个小伙伴在群里求助,说他这个 shell 脚本有问题,让大家帮忙看看

可以看到,这个脚本首先将目标文本文件的名字当作该脚本的第一个参数($1)传递进去,然后查看这个文本文件的内容(cat $1),并将内容赋值给 firstLine 变量
接着对文本内容的每一行进行遍历然后正则匹配,并将匹配到的内容绿色高亮输出出来,不匹配的内容红色高亮输出,并显示提示信息
其中,正则匹配表达式^\[(\d+)+\].+$ 匹配一组方括号 [ ] ,方括号后还有内容且方括号之间由数字组成:
第一部分:
^\[(\d+)+\]^\[ 表示以 [ 开头,\ 为转义字符
(\d+) +表示匹配多个数字,\ 为转义字符
\] 表示匹配右方括号,\ 为转义字符
第二部分:
.+$.+ 表示匹配任意字符
$ 表示结尾
因此上面的正则表达式可以匹配:[123] this is a test line 这样的内容
我们来执行一下这个脚本,首先看下目标文件内容


由脚本的执行结果得知,文本文件中的内容均没有匹配到
奇怪,正则表达式写的没有问题,为啥脚本里面的正则不匹配呢
定位问题
在解决这个问题之前,我们先来了解一下正则表达式(Regular Expression)
什么是正则表达式
正则表达式是一种通用的文本匹配工具
它允许你使用特定的语法来描述和匹配文本中的模式,可以说是描述文本内容组成规律的表示方式
正则表达式的发展史
正则表达式的起源,可以追溯到早期神经系统如何工作的研究
在 20 世纪 40 年代,有两位神经生理学家(Warren McCulloch 和 Walter Pitts),研究出了一种用数学方式来描述神经网络的方法
1956 年,一位数学家(Stephen Kleene)发表了一篇标题为《神经网络事件表示法和有穷自动机》的论文。这篇论文描述了一种叫做「正则集合(Regular Sets)」的符号
随后,大名鼎鼎的 Unix 之父 Ken Thompson 于1968年发表了文章《正则表达式搜索算法》,并且将正则引入了自己开发的编辑器 qed,以及之后的编辑器 ed 中,然后又移植到了大名鼎鼎的文本搜索工具 grep 中
自此,正则表达式被广泛应用到 Unix 系统或类 Unix 系统 (如 macOS、Linux) 的各种工具中,但是百家争鸣的场面使得各种语言和工具中的正则虽然功能大致类似,但仍然有不少细微差别
正则表达式两种流派之 POSIX 流派
上个世纪八十年代,POSIX (Portable Operating System Interface) 标准公诸于世,它制定了不同的操作系统都需要遵守的一套规则
其中就包括正则表达式的规则,遵循 POSIX 标准的正则表达式,称为 POSIX 派系正则表达式
POSIX 规范定义了正则表达式的两种标准
基本正则表达式 BRE(Basic Regular Expression)
不支持量词问号和加号,也不支持多选分支结构管道符
扩展正则表达式 ERE(Extended Regular Expression)
BRE 在使用花括号,圆括号时要转义才能表示特殊含义。由于BRE 功能不够强大,导致了 ERE 扩展标准的诞生
像 Unix 系统或类 Unix 系统上的大部分工具,如 grep 、sed 、awk 等都属于 POSIX 派系
BRE 标准和 ERE 标准
早期 BRE 与 ERE 标准的区别主要在于,BRE 标准不支持量词问号和加号,也不支持多选分支结构管道符
BRE 标准在使用花括号,圆括号时要转义才能表示特殊含义。BRE 标准用起来这么不爽,于是有了 ERE 标准,在使用花括号,圆括号时不需要转义了,还支持了问号、加号和多选分支
我们现在使用的 Linux 发行版,大多都集成了 GNU 套件。GNU 在实现 POSIX 标准时,做了一定的扩展,主要有以下三点扩展
GNU BRE 支持了
+、?,但转义了才表示特殊含义,即需要用\+、\?表示GNU BRE 支持管道符多选分支结构,同样需要转义,即用
\|表示GNU ERE 也支持使用反引用,和 BRE 一样,使用
\1、\2…\9表示

POSIX 字符组
POSIX 流派还有一个特殊的地方,就是有自己的字符组,叫 POSIX 字符组

正则表达式两种流派之 PCRE 流派
除了 POSIX 标准外,还有一个 Perl 分支,随着 Perl 语言的发展,Perl 语言中的正则表达式功能越来越强悍,为了把 Perl 语言中正则的功能移植到其他语言中,我们熟知的 PCRE 就诞生了
PCRE 是一个兼容 Perl 语言正则表达式的解析引擎,是由 Philip Hazel 开发的,为很多现代语言和工具所普遍使用
除了 Unix 上的工具遵循 POSIX 标准,PCRE 现已成为其他大部分语言和工具隐然遵循的标准
目前大部分常用编程语言都是源于 PCRE 标准,这个流派显著特征是有 \d、\w、\s 这类字符组简记方式
在 UNIX/LINUX 系统里 PCRE 流派与 POSIX 流派的对比,可以参考下表

在 Linux 中使用正则
在遵循 POSIX 规范的 UNIX/Linux 系统上,按照 BRE 标准 实现的有 grep、sed 和 vi/vim 等
而按照 ERE 标准 实现的有 egrep、awk 等
但是在 Linux 的 bash 中,原生的正则表达式语法是基于 POSIX 标准的(支持 ERE 标准和 BRE 标准),不直接支持 PCRE 标准
在了解完正则表达式之后,我们再回到问题本身
脚本中的正则表达式出现了 \d ,而 \d 是属于 PCRE 标准,而 Linux Bash (基于 POSIX 标准)不支持 PCRE 标准,所以匹配不到
3.解决问题
知道了 Linux Bash 不支持 PCRE 标准,我们将脚本中的正则表达式由 PCRE 标准改成 ERE 标准即可
改成 ERE 标准

- 修改脚本:在脚本里面使用 grep 进行正则匹配过滤
-P 参数表示支持 PCRE 正则
-v 参数表示取反操作

看下执行结果

参考链接:
https://zq99299.github.io/note-book/regular/03/03.html#正则表达式简史
https://askubuntu.com/questions/1143710/regex-with-d-doesn-t-work-in-if-else-statement-with
bash shell 无法使用 perl 正则的更多相关文章
- 单行bash、shell、perl命令
主题:单行经典bash.shell.perl命令 作者:luomg 摘要: 会陆陆续的写自己工作中的常用有意思的命令,争取你能看完后就能搞定常见操作, 且尽量自少提供基本shell.perl的实现方式 ...
- (转)linux bash shell 入门教程
Shell Script(bash)简介 众所皆知地,UNIX上以小工具著名,利用许多简单的小工具,来完成原本需要大量软体开发的工作,这一点特色,使得UNIX成为许多人心目中理想的系统平台. 在众多的 ...
- linux杂记(十)what is BASH Shell
first,what is shell?其实只要是碰过计算机的,对于OS(Operation System操作系统,不管是linux.unix.windows)有点概念的人大多都听过这个名词,因为只要 ...
- Linux Shell——bash shell 脚本简介
bash shell 脚本简介 shell 运行环境 如果你运行的是 Unix 或 Linux 系统,例如 Ubuntu,Red Hat,SUSE Linux,还有macOS,都是内置了 bash s ...
- Bash shell编程的语法知识点(1)
Bash shell脚本编程知识点如下(初学,不全,欢迎讨论补充): shell简介 脚本的简单介绍 变量和引用 算术运算 交互式编程 选择判断 条件测试 循环 函数 shell简介 shell是一种 ...
- [转帖][Bash Shell] Shell学习笔记
[Bash Shell] Shell学习笔记 http://www.cnblogs.com/maybe2030/p/5022595.html 阅读目录 编译型语言 解释型语言 5.1 作为可执行程序 ...
- VIM 正则表达式详解及与 perl 正则的区别
转载自:http://www.xuebuyuan.com/806332.html:个人进行了一些修正和添加. 下面我们对 VIM 正则表达式进行介绍并会显示指出其与 Perl 正则的不同之处. 字符集 ...
- ~/.bashrc的常用alias设置,30 个方便的 Bash shell 别名
centos6.5/centos7系统中,alias定义在/etc/bashrc,分别写在/etc/profile.d/*.sh中,可以在此目录添加my.sh,或者~/.bashrc,或者~/.bas ...
- bash shell
Linux的shell 与windows只有一种批处理脚本不同,由于早年的Unix年代,发展者众,出现了各种不同的distribution,因此也随着不同的distribution出现了各自的shel ...
- Bash Shell内建命令和保留字
Bash Shell内建命令和保留字命令含义!保留字,逻辑非:不做任何事,只做参数展开.读取文件并在shell中执行它alias设置命令或命令行别名bg将作业置于后台运行bind将关键字序列与read ...
随机推荐
- Python+unittest+requests 接口自动化测试框架搭建 完整的框架搭建过程 实战
一.Python+unittest+requests+HTMLTestRunner 完整的接口自动化测试框架搭建_00--框架结构简解 首先配置好开发环境,下载安装Python并下载安装pycharm ...
- pntia7-7 软硬车厢交替排列 (40 分)
7-7 软硬车厢交替排列 (40 分) 设车辆厂生产了硬座车厢和软座车厢共n节(混合在一起),要求使用队列的基本操作,编程实现所有硬座车厢和所有软座车厢交替排列. 例如硬座车厢用H来表示,软座车厢用S ...
- IDEA Maven 项目报错 java: 程序包org.springframework.beans.factory.annotation不存在
idea 刚把项目导进去的时候,点击运行,import的好多包都报红,所有的文件的Maven依赖包都没导入进去. 但只是第一个报错是: java: 程序包org.springframework.bea ...
- 图算法之BFS
深度优先搜索(Breadth First Search),类似于树的层序遍历,搜索模型是队列,还是以下面的无向图为例: 实验环境是Ubuntu 14.04 x86 伪代码实现如下: 其中u 为 v ...
- 【内存管理】CMA内存分配器(Contiguous Memory Allocator)
什么是CMA 参考这两篇博文,写得很好: http://www.wowotech.net/memory_management/cma.html https://www.cnblogs.com/Loye ...
- bigNumber.js的简单使用
sum 计算传入的参数和,参数类型可以是 String,Number // 两数之和 var x = BigNumber.sum('11', 23) x.toNumber() // 34 // 多个参 ...
- python 每天一个知识点 对文件的操作
对文件的操作: 操作 功能 文件对象 = open(file,mode,encoding) 打开文件获取文件对象 文件对象.read(num) 读取指定长度字节,不指定num读取文件全部 文件对象.r ...
- windows安装WinDump
1.下载软件,放在C盘: WinDump.exehttps://www.winpcap.org/windump/install/default.htmWinPcap_4_1_3.exe(windows ...
- C#向其实进程子窗体发送指令
近日,想在自己的软件简单控制其它软件的最大化最小化,想到直接向进程发送指令,结果一直无效,经过Spy++发现,原来快捷方式在子窗体上,所以需要遍历子窗体在发送指令,以下为参考代码: 1 [DllImp ...
- 如何优化if--else
1.现状代码 public interface IPay { void pay(); } package com.test.zyj.note.service.impl; import com.test ...