十二、Linux Shell脚本:正则表达式

简介: 正则表达式就是一套给文本“相亲”的规则,让你不再只能找“张三”,而是能找到所有“姓张、两个字、且名字里不带'伟'”的人。它通过一些“魔术符号”(元字符)来描述模式:比如 . 代表任意字符,* 代表重复任意次,^ 和 $ 则卡住行头行尾。把这些符号组合起来,你就能用grep或sed等工具,从海量文本里精确地捞出你想要的任何格式的数据。

正则表达式的本质是一套用于描述和匹配字符串集合规则模式语言 它通过组合普通字符和具有特殊含义元字符定义一个“模板”,然后用这个模板去文本中进行模式匹配

一、基本匹配 (字面量匹配)

最基础的正则表达式就是字符串本身,它会精确匹配文本中完全相同的字符序列。

代码示例 (使用 grep 命令演示):

# 在字符串中查找 "cat"
echo "My cat is black, your cat is white." | grep --color=always 'cat'
(--color=always 用于高亮匹配部分。为防止Shell对特殊字符进行解释,强烈建议将正则表达式用单引号 '' 包裹。)

二、核心元字符

正则表达式的威力来源于元字符,这些字符不再代表字面含义,而是被赋予了特殊的匹配功能

1.. (点) - 匹配任意单个字符

一个点 . 可以代表除换行符外任何一个字符。

# 匹配 "c" 和 "t" 之间有任意一个字符的模式
echo "cat cot c-t c@t chart" | grep --color=always 'c.t'
# 将匹配 cat, cot, c-t, c@t

2.* (星号) - 匹配前一个元素零次或多次

星号 * 表示其紧邻的前一个字符或分组可以出现任意次数 (0, 1, 2, ...)。

# 匹配 "go" 和 "gle" 之间有任意数量 "o" 的模式
echo "ggle google goooogle gogle" | grep --color=always 'go*gle'
# 将匹配 ggle (o出现0次), google, goooogle

3.+ (加号) - 匹配前一个元素一次或多次

加号 + 与星号类似,但要求其前一个元素至少出现一次 (1, 2, 3, ...)。

# 匹配 "go" 和 "gle" 之间至少有一个 "o" 的模式
echo "ggle google goooogle gogle" | grep -E --color=always 'go+gle'
# 将匹配 google, goooogle,但不匹配 ggle
注意 - 正则表达式方言 (Flavor):
+, ?, |, () 等元字符,在 基础正则表达式 (BRE) 中 (如标准 grep) 需要前置反斜杠 \ (如 \+) 才能生效。而在 扩展正则表达式 (ERE) 中 (如 grep -Eegrep) 则 直接使用。为 方便和现代,本教程的示例 主要使用 ERE

### 4.? (问号) - 匹配前一个元素零次或一次
问号 ? 表示其 前一个元素是 可选的
bash # 匹配 "color" 和 "colour" echo "color colour counselor" | grep -E --color=always 'colou?r'

### 5.^ (尖角号) - 匹配行首
^ 位于 正则表达式的开头时,它 锚定匹配必须从 一行的开始处发生。
bash # 匹配以 "start" 开头的行 echo -e "start of the line\nmiddle start end" | grep -E --color=always '^start' # 只会匹配第一行

### 6.$ (美元符) - 匹配行尾
$ 位于 正则表达式的末尾时,它 锚定匹配必须在 一行的结束处结束。
bash # 匹配以 "end" 结尾的行 echo -e "the line must end\nend of the line" | grep -E --color=always 'end$' # 只会匹配第一行
组合使用 ^$ 可以进行 整行匹配。例如 ^root$ 只匹配 内容仅为 "root" 的行。

### 7.[...] (方括号) - 匹配字符集合
方括号 [...] 定义了一个 字符集,它会匹配 集合内任意一个字符。
> [abc]: 匹配 'a', 'b', 'c' 中的 一个
[0-9]: 匹配 任意一个数字。
[a-z]: 匹配 任意一个小写字母。
[a-zA-Z]: 匹配 任意一个字母。
[^abc]: (当 ^在方括号 内开头时) 反向匹配,匹配 除 'a', 'b', 'c' 之外的任意一个字符。
bash # 匹配 "log" 后跟任意一个数字,然后是 ".txt" echo "log1.txt logA.txt log-3.txt" | grep -E --color=always 'log[0-9]\.txt' # 将匹配 log1.txt

### 8.\ (反斜杠) - 转义元字符
反斜杠 \ 用于 去除其后 元字符的特殊含义,使其 变回字面字符。例如,要匹配一个 真正的点 .,必须写成 \.

## 三、量词与分组

1. 精确量词 {}

花括号 {} 用于精确控制前一个元素重复次数

  • {n}: 正好 n 次。
  • {n,}: 至少 n 次。
  • {n,m}: n 到 m 次 (包含n和m)。
    # 匹配一个4位数的年份
    echo "Date: 2024, Item: 123" | grep -E --color=always '[0-9]{4}'
    # 将匹配 2024
    

2. 分组 () 与或 |

  • 圆括号 (): 将多个字符组合成一个逻辑单元,可以对整个单元应用量词。默认情况下,() 还会捕获其匹配到的内容,用于后续引用
  • 竖线 |: 表示“或”关系,匹配其左边或右边的表达式。
# 匹配 "file.log" 或 "file.txt"
echo "file.log file.txt file.dat" | grep -E --color=always 'file\.(log|txt)'

# 匹配 "http://" 或 "https://", 后跟任意字符
echo "URL: https://example.com" | grep -E --color=always '(http|https)://.*'

四、常见应用场景与工具

正则表达式在Linux命令行中无处不在

  • grep: 文本搜索
  • sed: 流编辑器,用于文本替换和转换。
  • awk: 强大的文本处理语言。
  • find: -regex 选项支持基于路径的正则匹配
  • 文本编辑器: vim, emacs 等都内置了强大的正则搜索/替换功能。
  • 编程语言: Python (re), Perl, JavaScript (RegExp), Java (java.util.regex) 等几乎所有语言都提供了正则库。

五、更多信息

  • POSIX 字符类: 为了更好的可移植性对非ASCII字符的支持,可以使用 [[:...:]] 形式的字符类,例如 [[:digit:]] 等同于 [0-9][[:alpha:]] 等同于 [a-zA-Z]
  • 贪婪与非贪婪匹配: 默认情况下,像 *+ 这样的量词是贪婪的,即它们会尽可能多地匹配字符。在支持PCRE (Perl Compatible Regular Expressions) 的引擎中 (如 grep -P),可以在量词后添加 ? (如 *?, +?) 来切换到非贪婪模式,即尽可能少地匹配。
总结: 正则表达式是 处理和分析文本数据的 基石。从 简单的字面量匹配,到 组合使用元字符、量词、分组和锚点,可以 构建出极其 精确和灵活匹配模式。熟练掌握 正则表达式极大地提升你在 命令行脚本编程中的 工作效率

---

## 练习题

题目一:基本匹配与元字符
写一个正则表达式,匹配包含 colorcolour 这两个单词的行。

题目二:数字匹配
写一个正则表达式,匹配一个三位数的整数。

题目三:开头与结尾
写一个正则表达式,匹配以大写字母开头,并且以句号 . 结尾的整行。

题目四:字符集合
写一个正则表达式,匹配一个小写元音字母 (a, e, i, o, u)。

题目五:量词
写一个正则表达式,匹配一个由至少两个数字组成的字符串。

题目六:转义
写一个正则表达式来精确匹配字符串 127.0.0.1

题目七:分组与或
写一个正则表达式,匹配 apple.jpgapple.png

题目八:综合应用 (简单邮箱格式)
写一个非常简化的正则表达式,尝试匹配类似 user@example.com 格式的字符串(假设用户名和域名只包含字母、数字、下划线,并且域名只有两部分)。

题目九:反向匹配
写一个正则表达式,匹配不包含任何数字的行。

题目十:POSIX字符类
使用POSIX字符类,写一个正则表达式,匹配一个或多个十六进制字符 (0-9, a-f, A-F)。

答案与解析

答案一:

colou?r
  • 解析: ? 量词表示其前一个字符 (u) 可以出现0次或1次,因此可以同时匹配 colorcolour

答案二:

[0-9]{3}
  • 解析: [0-9] 匹配任意一个数字{3} 这个量词表示前面的元素必须正好出现3次。如果要求整行就是三位数,应写成 ^[0-9]{3}$

答案三:

^[A-Z].*\.$
  • 解析: ^ 匹配行首[A-Z] 匹配一个大写字母.* 匹配任意数量的任意字符,\. 匹配一个字面上的点$ 匹配行尾

答案四:

[aeiou]
  • 解析: [...] 字符集会匹配其中列出任意一个字符。

答案五:

[0-9]{2,}
  • 解析: {2,} 量词表示前面的元素 ([0-9]) 必须出现至少2次

答案六:

127\.0\.0\.1
  • 解析: IP地址中的.元字符,必须使用反斜杠 \ 进行转义,才能匹配其字面含义

答案七:

apple\.(jpg|png)
  • 解析: \. 匹配(jpg|png) 使用分组 ()| 来匹配 jpgpng 字符串。

答案八:

[a-zA-Z0-9_]+@[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+
  • 解析: [a-zA-Z0-9_]+ 匹配至少一个字母、数字或下划线,用于匹配用户名域名部分@\. 匹配字面符号。这是一个简化模型

答案九:

^[^0-9]*$
  • 解析: ^$ 锚定整行[^0-9] 是一个反向字符集,匹配任何非数字字符。* 表示这些非数字字符可以出现任意次数 (包括0次,以匹配空行)。

答案十:

[[:xdigit:]]+
  • 解析: [[:xdigit:]]POSIX字符类,专门用于匹配十六进制字符 (等效于 [0-9a-fA-F])。+ 表示匹配一次或多次。使用POSIX字符类可读性更好兼容性更强
目录
相关文章
|
5月前
|
Shell Linux
九、Linux Shell脚本:运算符与表达式
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
430 0
|
5月前
|
Linux Shell 数据处理
十三、Linux Shell脚本:文本处理三剑客之 sed 与 awk
如果说grep是文本处理的“探照灯”,那sed和awk就是“手术刀”和“瑞士军刀”。sed 擅长按行“动手术”,可以轻松地删除、打印或替换特定行的内容,尤其是它的替换功能(s/.../.../)非常强大。而 awk 更厉害,它天生就能看懂按列(字段)分布的数据,像个小型的Excel。你可以让它只打印某几列,或者根据某一列的值做计算和判断,特别适合生成统计报告。
513 1
|
5月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
507 2
|
5月前
|
安全 Linux Shell
四、Linux核心工具:Vim, 文件链接与SSH
要想在Linux世界里游刃有余,光会“走路”还不够,还得配上几样“高级装备”。首先是Vim编辑器,它像一把瑞士军刀,让你能在命令行里高效地修改文件。然后要懂“软硬链接”,软链接像个快捷方式,硬链接则是给文件起了个别名。最后,SSH是你的“传送门”,不仅能让你安全地远程登录服务器,还能用scp轻松传输文件,设置好密钥更能实现免-密登录,极大提升效率。
435 4
|
5月前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
603 1
二、Linux文本处理与文件操作核心命令
|
5月前
|
监控 Shell Linux
十、Linux Shell脚本:流程控制语句
要让脚本从简单的“指令清单”升级为能干的“小助手”,就需要用if教它根据条件做判断,用for和while循环让它重复处理任务,再用case语句帮它在多个选项中做出清晰的选择
414 1
|
5月前
|
存储 安全 Linux
三、Linux用户与权限管理详解
管理Linux系统就像当一个大楼的管家。首先,你得用useradd和passwd给新员工发“钥匙”(创建用户并设密码),并用groupadd把他们分到不同“部门”(用户组)。然后,你要为每个“房间”(文件或目录)设定规矩,这就是文件权限:用chmod命令设置谁(所有者、同部门、其他人)可以“进入”(x)、“读取”(r)或“写入”(w)。最后,用chown还能把房间的归属权转让给别人。
645 3
|
4月前
|
算法 搜索推荐 JavaScript
基于python智能推荐算法的全屋定制系统
本研究聚焦基于智能推荐算法的全屋定制平台网站设计,旨在解决消费者在个性化定制中面临的选择难题。通过整合Django、Vue、Python与MySQL等技术,构建集家装设计、材料推荐、家具搭配于一体的一站式智能服务平台,提升用户体验与行业数字化水平。
|
4月前
|
运维 开发者 Docker
一、Docker:一场颠覆应用部署与运维的容器革命
Docker的出现,就是为了解决“在我电脑上能跑”这个老大难问题。它像个魔法集装箱,把你的程序和它需要的所有东西(比如库、配置)都打包好,这样无论在哪运行,环境都一模一样。理解它很简单,就三个核心玩意儿:镜像是程序的“安装包”,容器是跑起来的程序,而仓库就是存放和分享这些“安装包”的地方。
469 6
|
5月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
525 9