1. 什么是正则表达式 (Regular Expression)
正则表达式是一套用于处理大量的文字、文本、字符串的规则和方法。
通过定义特殊的符号,系统管理员可以快速地过滤、替换或输出需要的字符串。
核心特点:
- 以行为单位进行处理(Linux中)。
- 用途:找内容(文件内容、文本字符串)。
- 支持工具:Linux“三剑客”(
grep,sed,awk)以及各种编程语言(Python, PHP, Perl等)。
2. 为什么要使用正则表达式
- 运维工作需求:大量过滤日志、找东西,化繁为简。
- 高效易用:规则简单,功能强大。
- 通用性:高级工具(三剑客)都支持。
3. 正则表达式 vs 通配符 (Wildcards)
这是初学者最容易混淆的地方,必须区分清楚。
| 特性 | 正则表达式 (Regex) | 通配符 (Wildcards) |
|---|---|---|
| 处理对象 | 文件内容、文本、字符串 | 文件名、目录名 |
| 命令支持 | grep, sed, awk, egrep | ls, cp, mv, find 等普通命令 |
| 符号含义 | * 表示前一个字符重复0次或多次 | * 表示任意所有字符 |
| 示例 | grep "oldboy" file.txt | ls *.txt |
区分技巧:
- 不需要思考的判断:三剑客(
grep,sed,awk)默认使用正则,其他命令多用通配符。 - 简单区分:找文件内容用正则,找文件名用通配符。
4. 正则表达式的分类 (POSIX规范)
Linux中的正则表达式分为两类:
4.1 基本正则表达式 (BRE - Basic Regular Expression)
- 支持工具:
grep,sed,vi等。 - 元字符:
^,$,.,*,[],[^],\。 - 注意:在BRE中,
?,+,{},|,()等被视为普通字符,如果想作为元字符使用,通常需要加反斜杠转义(如\{ \}),或者直接使用扩展正则。
4.2 扩展正则表达式 (ERE - Extended Regular Expression)
- 支持工具:
egrep,grep -E,awk,sed -r。 - 元字符:在BRE基础上增加了
+,?,|,(),{}等。 - 推荐:使用
grep -E或egrep可以直接支持所有符号,更加方便。
5. 正则表达式符号详解
5.1 基本正则符号 (BRE)
| 符号 | 含义 | 示例 | 说明 |
|---|---|---|---|
^ | 行首锚点 | ^word | 匹配以 word 开头的行。 |
$ | 行尾锚点 | word$ | 匹配以 word 结尾的行(注意行尾空格)。 |
^$ | 空行 | grep '^$' file | 匹配什么都没有的空行。 |
. | 任意单字符 | grep '.' file | 匹配任意一个字符(不包含换行符)。 |
* | 重复前一个字符 | 1* | 大坑注意:匹配前一个字符出现 0次 或 多次。.* 表示匹配所有内容(贪婪匹配)。 |
\ | 转义字符 | \. | 将特殊符号还原为普通字符(脱掉马甲)。如 \n (换行), \t (Tab)。 |
[] | 字符集合 | [abc] | 匹配 a 或 b 或 c 中的任意一个字符。 |
[^] | 取反集合 | [^abc] | 匹配除 a, b, c 之外的任意字符。 |
常见技巧:
- 过滤空行:
grep -v '^$' file.txt - 匹配任意字符:
.*(贪婪匹配,有多少匹配多少) - 括号内特性:
[]内的大部分符号没有特殊含义(如.就是点),但^在[]内部开头表示取反。
5.2 扩展正则符号 (ERE)
使用 egrep 或 grep -E
| 符号 | 含义 | 示例 | 说明 |
|---|---|---|---|
+ | 重复一次或多次 | a+ | 前一个字符至少出现1次。与 * (0或多) 的区别在于 + 不匹配空。 |
? | 重复0次或1次 | a? | 前一个字符出现0次或1次(可选)。 |
| | 或者 | a|b | 匹配 a 或者 b。常用于同时过滤多种条件。 |
() | 分组 | (abc)+ | 将 abc 作为一个整体进行匹配,也用于后向引用。 |
{} | 量词范围 | 8{3} | 前一个字符重复特定次数。 |
量词 {} 详解:
{n}: 重复 n 次。{n,}: 重复至少 n 次。{n,m}: 重复 n 到 m 次。- 示例:
egrep '8{3,5}'匹配连续出现3到5次的8。
6. 实战案例与避坑指南
6.1 经典“坑”
*号的含义:它不代表“任意”,而是代表“前一个字符的0次或多次”。1*: 匹配1,11, 甚至空字符串(因为0次也算匹配)。
- 贪婪匹配:
.*会尽可能多地匹配字符。 - 文件名 vs 内容:
ls *.txt是通配符,grep 'txt$'是正则。
6.2 身份证号码匹配 (课前例题)
需求:取出文件中正确的身份证号码(18位,最后一位可能是数字或X)。
分析思路:
- 身份证特征:18位。
- 前17位是数字,最后一位是数字或X。
- 简单实现:
[0-9]{17}[0-9X](需要配合扩展正则grep -E)
6.3 过滤配置文件
需求:排除文件中的注释行(#开头)和空行。
命令:
grep -v '^$' /etc/ssh/ssh_config | grep -v '^#'
# 或者使用扩展正则同时过滤
egrep -v '^$|^#' /etc/ssh/ssh_config
6.4 统计单词出现次数
面试题:统计 /etc/passwd 中每个单词出现的次数。
命令链:
# 1. 读取文件
cat /etc/passwd |
# 2. 将分隔符替换为空格 (tr)
tr "[0-9:/ x]" " " |
# 3. 换行显示每个单词 (xargs -n1 或 grep -o)
xargs -n1 |
# 4. 排序
sort |
# 5. 去重并计数
uniq -c |
# 6. 按数量倒序排序
sort -rn |
# 7. 取前几名
head
7. 总结
- BRE (基础):
^,$,.,*,[](够用,但写复杂规则累) - ERE (扩展):
+,?,|,(),{}(推荐使用egrep或grep -E) - 核心思想:找什么写什么,善用组合。
- 三剑客口诀:
grep: 过滤查找。sed: 取行、替换、修改。awk: 取列、统计计算。
提示:熟练掌握正则表达式是Linux高级运维的必经之路,多练习
grep匹配日志是最好的学习方法。
Comments NOTHING