Shell 编程 —— 正则表达式与文本处理器
目录
一. 正则表达式
1.1 定义
1.2 用途
1.3 Linux 正则表达式分类
1.4 正则表达式组成
(1)普通字符
(2)元字符:规则的核心载体
(3) 重复次数
(4)两类正则的核心区别与工具适配
二、文本处理器:grep/sed 的核心用法
2.1 grep:条件查找工具
(1)常用选项(高频必记)
(2)经典场景示例
2.2 sed:流编辑工具(补充适配正则的核心用法)
三、关键避坑与效率技巧
四.总结
一. 正则表达式
1.1 定义
-
正则表达式(Regular Expression, regex/regexp/RE)是一种用来描述字符串模式的规则。
-
功能:检索、替换、过滤符合特定规则的字符串。
1.2 用途
-
系统日志筛选(如定位“登录失败”“服务启动失败”)
-
配置文件解析
-
文本查找替换
-
脚本编程中的条件匹配
1.3 Linux 正则表达式分类
-
BRE (基础正则表达式)
-
传统语法,功能有限
-
量词
{}
需要转义\{n,m\}
-
+
,?
,()
需要转义 -
常用工具:
grep
、sed
-
-
ERE (扩展正则表达式)
-
功能更强大,语法简洁
-
+
,?
,()
,{}
,|
等无需转义 -
常用工具:
egrep
(grep -E
)、awk
-
sed
默认是 BRE 模式,若要使用 ERE 功能,需加-E
选项(如sed -E 's/(a|b)/x/g' file
),否则+
?
等元字符需转义;awk
本身支持 ERE 语法,无需额外加选项(如awk '/wo+od/' file
可直接匹配多个o
),这是awk
比grep
(默认 BRE)更灵活的点。
1.4 正则表达式组成
(1)普通字符
直接匹配自身,如字母(a-z
/A-Z
)、数字(0-9
)、标点(,
/.
)等,无特殊语法含义。
(2)元字符:规则的核心载体
元字符 | 作用描述 | BRE/ERE 用法差异 | 示例 | |||
---|---|---|---|---|---|---|
. | 匹配任意单个字符(不含 \r\n ) | 无差异 | a.c 匹配 abc /a1c /a#c | |||
[] | 匹配括号内任意一个字符(字符集) | 无差异 | [0-9] 匹配任意数字,[a-zA-Z] 匹配字母 | |||
[^] | 匹配括号外任意一个字符(否定字符集) | 无差异 | [^0-9] 匹配非数字,[^w]oo 匹配非 w 开头的 oo | |||
^ | ① 正则开头:匹配行首;② [] 内开头:否定 | 无差异 | ^the 匹配行首为 the 的行,[^abc] 否定字母 a/b/c | |||
$ | 匹配行尾 | 无差异 | end$ 匹配行尾为 end 的行,^$ 匹配空行 | |||
\ | 转义符:去除元字符特殊含义 | 无差异(BRE 需转义的元字符更多) | a\.b 匹配 a.b (避免 . 匹配任意字符) | |||
* | 匹配前一子表达式 0 次或多次 | 无差异 | ab*c 匹配 ac /abc /abbc | |||
+ | 匹配前一子表达式 1 次或多次 | BRE 需转义 \+ ,ERE 直接用 + | BRE:a\+c ;ERE:a+c (均匹配 ac /aac ) | |||
? | 匹配前一子表达式 0 次或 1 次 | BRE 需转义 \? ,ERE 直接用 ? | BRE:bes\?t ;ERE:bes?t (均匹配 bet /best ) | |||
() | 分组:将多个字符视为一个整体 | BRE 需转义 \(\) ,ERE 直接用 () | BRE:`t(a\ | e)st;ERE:\ t(a | e)st(均匹配 tast/ test`) | |
{n}/{n,}/{n,m} | 精确匹配 n 次 / 至少 n 次 /n~m 次 | BRE 需转义 \{n\} ,ERE 直接用 {n} | BRE:o\{2\} ;ERE:o{2} (均匹配 oo ) | |||
` | ` | 逻辑 “或”:匹配多个表达式之一 | BRE 需转义 | ,ERE 直接用 ` | ` | BRE:a|b ;ERE:`a | b(均匹配 a或 b`) |
(3) 重复次数
* 0 次或多次匹配前面子表达式0次或者多次 例:goo*d、go.*d
\+ 至少 1 次匹配其前面的字符出现最少1次,即:肯定有且 >=1 次
\{n\} 恰好 n 次匹配前面的子表达式n次,例:go\{2\}d、'[O-9]\{2\}'匹配两位数字
\{m,n\} m 到 n 次匹配前面的子表达式n到m次,例: go\{2,3\)d、'[0-9]\{2,3\}'匹配两位到三位数字
\{n,\} 至少 n 次匹配前面的子表达式不少于n次,例: go\{2,\}d、' [0-9]\{2,\}'匹配两位及两位以上数字
扩展:
egrep、awk使用{n}、{n, }、{n, m}匹配时“{}"前不用加"\”
egrep -E -n 'wo{2}d' test.txt //-E 用于显示文件中符合条件的字符
egrep -E -n 'wo{2,3}d' test.txt
案列:
+ 作用:重复一个或者一个以上的前一个字符
示例:执行“egrep -n 'wo+d' test.txt”命令,即可查询"wood" "woood" "woooooood"等字符串
? 作用:零个或者一个的前一个字符
示例:执行“egrep -n 'bes?t' test.txt”命令,即可查询“bet”“best”这两个字符串
| 作用:使用或者(or)的方式找出多个字符
示例:执行“egrep -n 'of|is|on' test.txt”命令即可查询"of"或者"if"或者"on"字符串
() 作用:查找“组”字符串
示例:“egrep -n 't(a|e)st' test.txt”。“tast”与“test”因为这两个单词的“t”与“st”是重复的,所以将“a”与“e”
列于“()”符号当中,并以“|”分隔,即可查询"tast"或者"test"字符串
()+ 作用:辨别多个重复的组
示例:“egrep -n 'A(xyz)+C' test.txt”。该命令是查询开头的"A"结尾是"C",中间有一个以上的"xyz"字符串的意思
(4)两类正则的核心区别与工具适配
维度 | 基础正则(BRE) | 扩展正则(ERE) | |
---|---|---|---|
语法特点 | 功能有限,部分元字符需转义 | 功能更全,元字符无需转义 | |
关键元字符转义要求 | + /? /() /{} 需加 \ (如 a\+ /a\{2\} ) | + /? /() /{} /` | 原生支持(如 a+/ a{2}`) |
常用工具 | grep (默认)、sed (默认) | grep -E /egrep 、sed -E 、awk (默认) | |
工具适配补充 | sed 需加 -E 才能启用 ERE 功能 | awk 天生支持 ERE,无需额外选项 |
二、文本处理器:grep/sed 的核心用法
文本处理器是正则的 “执行工具”,grep
专注行级匹配过滤,sed
专注流编辑(替换 / 删除 / 插入),两者均需结合正则实现功能。
2.1 grep:条件查找工具
(1)常用选项(高频必记)
选项 | 作用 | 示例 |
---|---|---|
-n | 显示匹配行的行号 | grep -n 'the' test.txt |
-i | 忽略大小写匹配 | grep -i 'The' test.txt |
-v | 反向匹配:输出不包含匹配内容的行 | grep -v 'ignore' test.txt |
-c | 统计匹配行的数量 | grep -c 'root' /etc/passwd |
-o | 只输出匹配的内容(而非整行) | grep -o '[0-9]\+' test.txt (提取所有数字) |
-E | 启用扩展正则(等价于 egrep ) | grep -E 'wo+od' test.txt (匹配 wood /woood ) |
-r | 递归查找目录下所有文件 | grep -r -n 'ERROR' /var/log (递归查找日志中的错误行) |
--color=auto | 高亮显示匹配内容 | grep --color=auto 'root' /etc/passwd |
(2)经典场景示例
- 提取 IP 地址(严谨版,避免无效 IP):
grep -E -o '([0-9]{1,3}\.){3}[0-9]{1,3}' ifconfig.out
- 过滤空行:
grep -v '^$' test.txt
- 匹配行首为数字的行:
grep -n '^[0-9]' test.txt
2.2 sed:流编辑工具(补充适配正则的核心用法)
- 替换操作:
sed 's/旧内容/新内容/选项' 文件名
,选项g
表示全局替换(一行内所有匹配),-i
表示就地修改(建议加.bak
备份:sed -i.bak 's/old/new/g' file
)- BRE 示例:
sed 's/wo\{2\}d/WOOD/g' test.txt
(将wood
替换为WOOD
) - ERE 示例:
sed -E 's/wo{2,}d/WOOD/g' test.txt
(将wood
/woood
等替换为WOOD
)
- BRE 示例:
- 删除操作:
sed '/匹配规则/d' 文件名
,如删除空行:sed '/^$/d' test.txt
,删除行首为#
的注释行:sed '/^#/d' test.txt
三、关键避坑与效率技巧
- 转义符陷阱:BRE 中
+
/?
/()
/{}
必须转义,否则会被当作普通字符;建议优先用 ERE(grep -E
/sed -E
)减少转义负担。 ^
的歧义:务必区分 “正则开头的^
(行首)” 和 “[]
内的^
(否定)”,避免混淆匹配逻辑(如^[0-9]
是行首数字,[^0-9]
是非数字)。- 工具适配优先级:
- 简单行过滤:用
grep
(快且直观) - 文本替换 / 删除:用
sed
(支持正则批量处理) - 字段级统计(如按逗号分割求和):用
awk
(天生支持 ERE,适合字段处理)
- 简单行过滤:用
- 安全操作:使用
sed -i
就地修改前,先不加-i
预览效果(sed 's/old/new/g' file
),或加备份(sed -i.bak ...
),避免误删数据。
四.总结
正则表达式是 “规则”,文本处理器是 “执行工具”:
- 先明确需求(匹配 / 提取 / 替换 / 统计),再选择正则类型(BRE 简单场景,ERE 复杂场景);
- 工具选择遵循 “最小功能原则”:行过滤用
grep
,编辑用sed
,字段统计用awk
; - 记忆元字符时,优先掌握
^
/$
(行锚点)、[]
/[^]
(字符集)、*
/+
/?
(重复次数),这三类是 80% 场景的核心。