shell--通配符
Shell 通配符
一、基础通配符
星号*
匹配零个或多个任意字符(包括空字符)
- 示例:
1
2
3*.txt # 匹配所有.txt文件(如file.txt、.txt等)
doc* # 匹配以doc开头的文件(如document、doc1)
*log* # 匹配包含log的文件(如log.txt、error_log)
问号?
匹配单个任意字符
- 示例:
1
2file?.txt # 匹配file1.txt、fileA.txt(不匹配file10.txt)
image?.png # 匹配image1.png、imageX.png
方括号[]
匹配指定字符集中的一个字符
- 扩展用法:
1
2
3
4[a-z] # 匹配任意小写字母
[0-9] # 匹配数字
[A-Za-z] # 匹配任意字母
[!aeiou] # 排除元音字母(需配合shopt -s extglob)
花括号{}
(扩展匹配)
生成模式组合的笛卡尔积
- 示例:
1
2{2022,2023}-{Q1,Q2} # 生成:2022-Q1 2022-Q2 2023-Q1 2023-Q2
file{1..3}.txt # 生成:file1.txt file2.txt file3.txt
二、高级通配符(需开启extgonglob)
1 | shopt -s extglob # 启用扩展模式(建议在脚本开头设置) |
模式匹配符
通配符 | 说明 | 示例 |
---|---|---|
?(x) |
匹配0或1次x | file-?(abc) |
*(x) |
匹配0次或多次x | log*(.old) |
+(x) |
匹配1次或多次x | error+(.log) |
@(x) |
精确匹配1次x | image@(.png) |
!(x) |
排除匹配x的内容 | !(*.bak) |
案例1:文件匹配
贪婪匹配遵循最左最长原则,如下
1 | # 匹配 log 文件及其任意数量的 .bak 后缀 |
- 匹配结果:
log(0次匹配)
log.bak(1次匹配)
log.bak.bak(2次匹配)
log.bak.bak.bak…(N次匹配) - 不匹配:
log.txt(包含其他扩展名)
bak.log(模式顺序错误)
ru单个?
只能占一个字符,但连续多个?依旧遵循“最左最长”:
1 |
|
案例2:目录清理
1 | # 删除所有临时文件(包括无后缀和多级后缀) |
- 匹配:
file.tmp
file.tmp.tmp
data.tmp.backup(中间含.tmp)
隐藏开关速查
通过shopt
开启后,增加shell功能
1 | shopt -s 开关名 # 临时开启 |
开关名 | 作用简述 | 快速示例 |
---|---|---|
nocaseglob |
大小写不敏感 | ls *.JPG 也能匹配 a.jpg |
globstar |
** 递归任意层级 |
ls **/*.log |
dotglob |
* 匹配隐藏文件 |
rm * 会把 .cache 一起删掉 |
failglob |
无匹配时报错,防止误操作 | rm *.tmp 无文件时报错而非删光 |
nullglob |
无匹配时展开成空串 | for f in *.pdf; do …; done 更安全 |
extglob |
开启 ?(…) *(…) +(…) @(…) !(…) 语法 |
见本文第二章表格 |
三、注意事项
隐藏文件
- 默认不匹配以
.
开头的文件(需显式指定.*
)
- 默认不匹配以
路径分隔
*
不会跨目录匹配,如/etc/*.conf
仅匹配/etc目录下的conf文件
特殊字符处理
- 包含空格的文件名需加引号:
rm "file with spaces.txt"
- 包含空格的文件名需加引号:
转义字符
- 使用反斜杠转义特殊字符:
rm \*.txt
(实际删除名为*.txt的文件)
- 使用反斜杠转义特殊字符:
四、实际应用场景
批量操作
1
2
3
4
5# 重命名所有JPEG图片
mv *.jpeg *.jpg
# 删除临时文件
rm *.tmp选择性备份
1
cp /var/log/{access,error}.log /backup/
日志分析
1
grep "ERROR" app-2023-{01..12}-*.log
日志清理
1
2# 删除7天前且大于100MB的日志备份
find /var/log -name "*.log*(.gz|.bz2)" -size +100M -mtime +7 -delete组合排除逻辑
1
2# 匹配非图片文件(允许无后缀,但排除图片类型)
!(*.jpg|*.png|*.gif)递归目录处理
1
2# 查找所有含版本号的文件(如data_v1、data_v2_backup)
find . -name "data_v*([0-9])*"
五、与正则表达式的区别
特性 | Shell通配符 | 正则表达式 |
---|---|---|
匹配对象 | 文件名 | 文本内容 |
* 的含义 |
任意数量字符 | 前项0次或多次 |
范围表示 | [a-z] |
[a-z] 或[:lower:] |
扩展语法 | 需启用extglob | 支持多种修饰符 |