Shell 编程:正则表达式与文本处理器
1. 正则表达式 (Regular Expression)
1.1 定义与功能
定义:一种用于描述字符串匹配模式的规则,简称 regex/regexp/RE。
核心功能:检索、替换、过滤符合特定规则的文本。
1.2 主要用途
筛选系统日志(如“登录失败”、“服务启动失败”等)
解析配置文件
文本查找与替换
在脚本编程中作为条件进行匹配
1.3 Linux 中的分类
Linux 中的正则表达式主要分为两类,它们在语法和支持的元字符上有所不同。
分类 | 名称 | 特点 | 常用工具 | |
---|---|---|---|---|
BRE | 基础正则表达式 | 语法传统,功能有限。量词 {} 和字符 + , ? , () 等需要转义才能表示特殊含义。 | grep , sed (默认) | |
ERE | 扩展正则表达式 | 功能更强大,语法更简洁。+ , ? , () , {} , ` | ` 等元字符无需转义。 | egrep 或 grep -E , awk |
1.4 正则表达式构成
1.4.1 普通字符
字母、数字、标点等字符本身,匹配它们自己。
1.4.2 元字符 (Metacharacters)
具有特殊含义的字符,是正则表达式的核心。
元字符 | 功能描述 | 示例 |
---|---|---|
. | 匹配任意一个字符(换行符 \n 除外)。 | g. 匹配 ga , gb , g1 等 |
[] | 匹配字符集合中的任意一个字符。 | [abc] 匹配 a , b , 或 c |
[^] | 匹配不在集合中的任意一个字符。 | [^0-9] 匹配任意非数字字符 |
^ | 匹配行的开始位置。 | ^The 匹配以 The 开头的行 |
$ | 匹配行的结束位置。 | end$ 匹配以 end 结尾的行 |
\ | 转义字符,使其后的元字符失去特殊意义。 | a\.b 匹配 a.b ,而不是任意字符 |
1.4.3 次数限定符 (Quantifiers)
用于指定其前面的字符或子表达式出现的次数。
限定符 (BRE) | 限定符 (ERE) | 功能描述 | 示例 (BRE) | 示例 (ERE) |
---|---|---|---|---|
* | * | 匹配前一个字符 0 次或多次 | go*d (匹配 gd , god , good ) | 同上 |
\+ | + | 匹配前一个字符 至少 1 次 | go\+d (匹配 god , good ) | go+d |
\{n\} | {n} | 匹配前一个字符 恰好 n 次 | go\{2\}d (匹配 good ) | go{2}d |
\{n,\} | {n,} | 匹配前一个字符 至少 n 次 | go\{2,\}d (匹配 good , gooood ) | go{2,}d |
\{n,m\} | {n,m} | 匹配前一个字符 n 到 m 次 | go\{2,4\}d (匹配 good , gooood ) | go{2,4}d |
1.4.4 ERE 扩展元字符
元字符 | 功能描述 | 示例 | ||
---|---|---|---|---|
? | 匹配前一个字符 0 次或 1 次 | colou?r 匹配 color 和 colour | ||
**` | `** | 或操作,匹配符号两边的任意一个表达式 | `cat | dog匹配 cat或 dog` |
() | 定义一个子表达式或分组,用于限制范围或后续操作 | (abc)+ 匹配 abc , abcabc 等 |
2. grep
—— 文本搜索工具
grep
是使用正则表达式进行全局搜索的最常用工具。
常用选项
选项 | 描述 |
---|---|
-E | 使用扩展正则表达式 (ERE),等同于 egrep |
-c | 只输出匹配行的数量 |
-i | 忽略字符大小写 |
-o | 只输出匹配到的内容本身,而不是整行 |
-v | 反向匹配,输出不包含模式的行 |
-n | 显示匹配行的行号 |
--color=auto | 将匹配到的内容以颜色高亮显示 |
实用示例
# 统计 /etc/passwd 中包含 'root' 的行数 grep -c root /etc/passwd# 在 web.sh 中忽略大小写查找所有 'the' grep -i "the" web.sh# 显示 /etc/passwd 中不包含 'root' 的用户行 grep -v root /etc/passwd# 提取本机的第一个 IP 地址(使用 BRE) grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' ifconfig.out | head -1# 同上,但使用 ERE (grep -E 或 egrep) egrep -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' ifconfig.out | head -1
3. 元字符操作案例详解
假设操作文件为 test.txt
。
查找与反向查找
grep -n 'the' test.txt # 查找包含 'the' 的行并显示行号 grep -vn 'the' test.txt # 查找不包含 'the' 的行
字符集合
[]
grep -n 'sh[io]rt' test.txt # 匹配 'shirt' 或 'short' grep -n '[^Ww]oo' test.txt # 匹配 'oo',且前面不是字母 W 或 w
行首
^
与行尾$
锚点grep -n '^the' test.txt # 匹配以 'the' 开头的行 grep -n '\.$' test.txt # 匹配以点 '.' 结尾的行(点需转义) grep -n '^$' test.txt # 匹配所有空行
任意字符
.
和重复*
grep -n 'w..d' test.txt # 匹配像 'wood', 'w00d', 'w&&d' 的字符串(w 和 d 中间有两个字符) grep -n 'woo*d' test.txt # 匹配 'wd', 'wod', 'wood', 'woood' ... (o 出现 0 次或多次) grep -n 'w.*d' test.txt # 匹配 w 和 d 之间有任意数量任意字符的字符串 grep -n '[0-9][0-9]*' test.txt # 匹配包含任意数字的行(数字出现 1 次或多次)
次数限定
\{\}
(BRE)grep -n 'o\{2\}' test.txt # 匹配连续出现两个 'o' 的地方 grep -n 'wo\{2,5\}d' test.txt # 匹配 'wood' (2个o), 'wooood' (5个o) 等 grep -n 'wo\{2,\}d' test.txt # 匹配至少包含 2 个 'o' 的单词,如 'wood', 'woood'
扩展功能
+
,?
,|
,()
(ERE)egrep -n 'wo+d' test.txt # 匹配 'wod', 'wood', 'woood' ... (o 至少1次) egrep -n 'bes?t' test.txt # 匹配 'bet' 和 'best' (s 出现 0 次或 1 次) egrep -n 'of|is|on' test.txt # 匹配包含 'of' 或 'is' 或 'on' 的行 egrep -n 't(a|e)st' test.txt # 匹配 'tast' 或 'test' egrep -n 'A(xyz)+C' test.txt # 匹配以 A 开头、C 结尾,中间有至少一个 'xyz' 的字符串,如 'AxyzC', 'AxyzxyzC'