通配符与正则表达式
通配符(Globbing)
通配符是由 Shell 处理的特殊字符,用于路径或文件名匹配。当 Shell 在命令参数中遇到通配符时,会将其扩展为匹配的文件路径;若没有匹配项,则作为普通字符传递给命令。
Shell 中的通配符列表
通配符 | 描述 | 示例 |
---|---|---|
* | 匹配任意长度的字符(包括 0 个) | ls *.txt :匹配所有 .txt 文件 |
? | 匹配单个任意字符 | ls file?.txt :匹配 file1.txt 、fileA.txt 等 |
[charset] | 匹配字符集中的任意单个字符 | ls [abc].txt :匹配 a.txt 、b.txt 、c.txt |
[^charset] | 匹配不在字符集中的任意单个字符 | ls [^0-9].txt :匹配非数字开头的 .txt 文件 |
[a-z] | 匹配指定范围内的单个字符(小写字母) | ls [a-c]file :匹配 afile 、bfile 、cfile |
[[:class:]] | 匹配 POSIX 字符类中的字符 | ls [[:digit:]]* :匹配数字开头的文件 |
POSIX 字符类(需用 [[:class:]]
表示):
水平空白字符([:blank:]
)
定义:仅包含在同一行内起分隔作用的空白字符。
包含字符:
- 空格():ASCII 32(十进制),用于单词分隔。
- 制表符(
\t
):ASCII 9,用于文本对齐(水平跳格)
垂直空白字符([:space:])
定义:用于换行或分页的空白字符,会导致文本显示位置移动到新行或新页。
包含字符:
- 换行符(
\n
):ASCII 10,用于换行(如 Unix/Linux 系统的行尾符)。 - 回车符(
\r
):ASCII 13,用于回到行首(如 Windows 系统的行尾符为\r\n
)。 - 换页符(
\f
):ASCII 12,用于分页(如打印时换页)。 - 垂直制表符(
\v
):ASCII 11,用于垂直跳格(很少使用)。
字符类 | 描述 | 等价写法 |
---|---|---|
[:alnum:] | 字母或数字 | [A-Za-z0-9] |
[:alpha:] | 字母(大小写) | [A-Za-z] |
[:digit:] | 数字 | [0-9] |
[:lower:] | 小写字母 | [a-z] |
[:upper:] | 大写字母 | [A-Z] |
[:space:] | 空白字符(空格、制表符、换行符等) | — |
[:punct:] | 标点符号 | — |
通配符实例文件自己chuang
-
匹配以
menu0
开头的文件ls menu0* # 输出:menu01.sh menu02.sh menu03.sh menu04.sh
-
匹配以
m
开头且后接单个字符的文件ls m? # 输出:m1 m2 m3(假设存在这些文件)
-
匹配以
m
或n
开头的文件ls [mn]* # 匹配 `m*` 和 `n*` 的文件
-
匹配字母开头的文件(不区分大小写)
ls [a-Z]* # 注意:`[a-Z]` 实际包含 ASCII 字符范围,可能包含非字母(如 `[`、`\` 等),推荐用 `[[:alpha:]]` ls [[:alpha:]]* # 正确匹配所有字母开头的文件
-
匹配数字开头的文件
ls [[:digit:]]* # 等价于 `ls [0-9]*`
-
匹配字母或数字开头的文件
ls [[:alnum:]]* # 匹配 `[0-9A-Za-z]*`
grep的常用参数
选项 | 功能描述 |
---|---|
-n | 显示行号 |
-o | 只显示匹配的内容 |
-q | 静默模式,无输出,通过$? 判断执行是否成功(即是否过滤到想要内容) |
-l | 匹配成功则只打印文件名,失败不打印,常与-r 一起用,如grep -rl 'root' /etc |
-A <n> | 匹配成功时,将匹配行及其后n 行一起打印出来 |
-B <n> | 匹配成功时,将匹配行及其前n 行一起打印出来 |
-C <n> | 匹配成功时,将匹配行及其前后n 行一起打印出来 |
--color | 高亮颜色显示匹配到的字符串 |
-c | 匹配成功时,打印匹配到的行数 |
-E | 等同于egrep ,启用扩展正则表达式 |
-i | 忽略大小写 |
-v | 取反,打印不匹配的行 |
-w | 匹配单词 |
-r | 递归搜索,不仅搜索当前目录,还搜索各级子目录 |
-s | 不显示关于不存在或无法读取文件的错误信息 |
正则表达式(Regular Expression, RE)
正则表达式是用于文本内容匹配的模式,常用于 grep
、sed
、awk
等工具中,针对文件内容而非文件名。
正则表达式基础概念
- 作用:通过特殊字符组合,实现字符串的搜索、替换、删除等操作。
- 优势:简化文本处理逻辑,减少代码量。
- 分类:
- 基本正则表达式(BRE):支持基础元字符,需转义部分符号(如
{}
)。 - 扩展正则表达式(ERE):支持更多元字符(如
+
、?
),无需转义{}
等符号。
- 基本正则表达式(BRE):支持基础元字符,需转义部分符号(如
基本正则表达式(BRE)元字符
元字符 | 描述 | 示例 |
---|---|---|
^ | 匹配行首 | grep ^root /etc/passwd :匹配以 root 开头的行 |
$ | 匹配行尾 | grep bash$ /etc/passwd :匹配以 bash 结尾的行 |
. | 匹配单个任意字符 | grep r.t /etc/passwd :匹配 r 和 t 之间有一个字符的行(如 rot 、rxt ) |
* | 匹配前一个字符 0 次或多次 | grep r.*t /etc/passwd :匹配 r 和 t 之间有任意字符的行 |
[] | 匹配字符集中的任意单个字符 | grep r[a-z]t /etc/passwd :匹配 r 和 t 之间为小写字母的行 |
[^] | 匹配不在字符集中的任意单个字符 | grep r[^a-z]t /etc/passwd :匹配 r 和 t 之间为非小写字母的行 |
\{n,m\} | 匹配前一个字符 n 到 m 次(需转义) | grep 'r\{3\}t' /etc/passwd :匹配 r 重复 3 次后接 t 的行 |
POSIX 字符类(在正则中同样适用):
grep [[:digit:]]\{3,4\} /etc/passwd # 匹配 3-4 位数字
扩展正则表达式(ERE)元字符
需通过 egrep
或 grep -E
使用,无需转义特殊符号。
元字符 | 描述 | 示例与匹配结果 |
---|---|---|
+ | 匹配前一个字符 1 次或多次(至少出现 1 次)。 | egrep 'r+t' /etc/passwd 匹配 rt 、rrt 、rrrt 等(r 至少出现 1 次后接 t )。 |
? | 匹配前一个字符 0 次或 1 次(可选出现)。 | egrep 'colou?r' /etc/passwd 匹配 color 或 colour (u 可选:u可出现0次或者1次)。 |
{n} | 匹配前一个字符 恰好 n 次。 | egrep 'r{3}t' /etc/passwd 匹配 rrrt (r 连续出现 3 次)。 |
{n,} | 匹配前一个字符 至少 n 次。 | egrep 'r{2,}t' /etc/passwd 匹配 rrt 、rrrt 、rrrrrt 等(r 至少出现 2 次)。 |
{n,m} | 匹配前一个字符 n 到 m 次之间(包含 n 和 m)。 | egrep 'r{2,4}t' /etc/passwd 匹配 rrt 、rrrt 、rrrrt (r 出现 2-4 次)。 |
(pattern1|pattern2) | 匹配多个模式中的 任意一个(使用竖线 | 分隔)。 | egrep '^(root|admin)' /etc/passwd 匹配以 root 或 admin 开头的行。 |
正则表达式工具对比
工具 | 正则类型 | 说明 |
---|---|---|
grep | 基本正则表达式(BRE) | 需转义 {} 等符号 |
egrep | 扩展正则表达式(ERE) | 直接使用 + 、? 、{} 等符号 |
fgrep | 不支持正则 | 按字面匹配字符串 |
正则表达式实例
-
匹配以
bash
结尾的行grep bash$ /etc/passwd # 基本正则 egrep bash$ /etc/passwd # 扩展正则(等价)
-
匹配 3-4 位数字
grep '[[:digit:]]\{3,4\}' /etc/passwd # BRE,需转义 {} egrep '[[:digit:]]{3,4}' /etc/passwd # ERE,无需转义
-
匹配以空白字符开头、非空白字符后跟的行
grep "^[[:space:]]\+[^[:space:]]" /etc/grub2.cfg # BRE,`\+` 表示 `+` egrep "^[[:space:]]+[^[:space:]]" /etc/grub2.cfg # ERE,直接用 `+`
-
匹配包含
Failed
或FAILED
的行(不区分大小写)grep -i 'failed' /var/log/secure # 基本正则,`-i` 忽略大小写 egrep -i 'failed|FAILED' /var/log/secure # 扩展正则,匹配任意模式
通配符与正则表达式对比
特性 | 通配符 | 正则表达式 |
---|---|---|
处理者 | Shell(路径扩展) | 命令(如 grep ) |
作用对象 | 文件名或路径 | 文本内容 |
元字符差异 | * 、? 、[] | .* 、+ 、() 等 |
典型场景 | ls *.txt 、rm data_* | grep "pattern" file 、sed -e "s/regex/replace/" |
7.4 练习与答案(扩展)
练习 1:显示 /etc/passwd
中以不区分大小的 h
开头的行
grep -i ^h /etc/passwd # `-i` 忽略大小写,`^h` 匹配行首
练习 2:显示 /etc/passwd
中以 sh
结尾的行
grep sh$ /etc/passwd # `$` 匹配行尾
练习 3:显示 /etc/fstab
中以 #
开头、后跟一个或多个空白字符和非空白字符的行
grep "^#[[:space:]]\+[^[:space:]]" /etc/fstab # BRE,`\+` 表示一个或多个空白字符
egrep "^#[[:space:]]+[^[:space:]]" /etc/fstab # ERE,直接用 `+`
练习 4:查找 /etc/rc.d/rc.local
中包含以 to
开始并以 to
结尾的字串的行
grep "to.*to" /etc/rc.d/rc.local # `.*` 匹配任意字符
练习 5:查找 /etc/passwd
中包含sbin行,或者以s开头,以n结尾的单词的行
1、grep -w 'sbin' /etc/passwd # `\<` 和 `\>` 表示单词边界
-w 会强制 grep 仅匹配独立的完整单词,而非单词的一部分。具体规则:
单词边界:单词必须被非单词字符(如空格、标点符号、换行符)包围。
单词字符:通常指字母、数字和下划线(即 [A-Za-z0-9_])。
选项 / 元字符 功能 示例匹配
-w 匹配完整单词,自动添加单词边界检查 grep -w 'foo' → 匹配 foo,但不匹配 foobar
\< 和 \> 正则表达式中的单词边界元字符 grep '\<foo\>' → 同上,但需手动添加元字符
2、grep -Eo '\bs[a-z]*n\b' /etc/passwd # 仅匹配小写字母
-o 是只显示匹配内容
\b:显式定义单词边界
grep -Ew 's[a-z]*n' /etc/passwd
注意:如果你要匹配以s开头,以n结尾单词的行,根据grep版本的问题,.*进行贪婪匹配,会尽可能多的去匹配,达不到预期的效果,所以我们把任意字符改为任意数量的小写字母。
练习 6:查找 ifconfig
结果中 1-255 之间的整数
ifconfig | egrep -w "[1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]"
练习 7:显示 /var/log/secure
中包含 Failed
或 FAILED
的行
grep -i 'failed' /var/log/secure # 简化写法,匹配大小写
练习 8:在 /etc/passwd
中取出默认 Shell 为 bash
的行
grep '/bin/bash$' /etc/passwd # 匹配行尾的 `/bin/bash`
练习 9:以长格式列出 /etc/
下以 ns
开头、.conf
结尾的文件
ls -l /etc/ns*.conf # 通配符直接用于文件名匹配
练习 10:高亮显示 passwd
文件中用户名和加密密码
grep -o '^[^:]*:[^:]*' /etc/passwd # 匹配冒号分隔的字段
相当于匹配用户名和加密密码
总结
- 通配符:专注于文件名匹配,由 Shell 处理,语法简单(如
*
、?
)。 - 正则表达式:用于文本内容匹配,支持复杂模式(如
^
、$
、.*
),需结合工具(grep
、egrep
)使用。 - 关键区别:作用对象不同(文件名 vs. 文本内容),元字符语法有差异。