通配符是Bash中由shell解析的文件名展开机制,非正则表达式;*匹配任意长度字符(不跨目录、不匹配隐藏文件),?匹配单字符,[]匹配字符集,{}为花括号扩展;需注意引号禁用展开、failglob报错控制及转义特殊字符。

通配符(Globbing)是 Bash 中由 shell 自己解析的模式匹配机制,不是正则表达式,也不依赖于命令本身。它在文件名展开(filename expansion)阶段起作用,发生在命令执行前,是批量处理文件最基础也最高效的手段。
常见通配符及其匹配逻辑
Shell 在执行命令前,会把含通配符的字符串替换成当前目录下实际匹配的文件名列表(若无匹配,默认原样保留——除非开启 failglob 选项)。
-
*:匹配任意长度的任意字符(包括空字符串),但不跨目录层级,且不匹配以点(.)开头的隐藏文件(除非显式写成
.*) - ?:匹配任意单个字符(不能是空,也不能是路径分隔符 /)
-
[abc]:匹配方括号中任意一个字符;支持范围写法如
[a-z]、[0-9A-F];开头为^或!表示取反,如[^0-9] -
[!a-z]:等价于
[^a-z],匹配非小写字母的单个字符 -
{a,b,c}:花括号扩展(brace expansion),属于 shell 展开的另一类机制,严格来说不算通配符,但常配合使用,例如
cp file.{txt,log} /backup/
避开常见陷阱的实操要点
通配符易用,但出错也隐蔽。几个关键细节决定成败:
- 通配符只在未加引号时才被 shell 展开;一旦用双引号或单引号包裹(如
"*.log"),就变成字面字符串,传给命令的是未展开的星号本身 -
rm *.log若当前无 .log 文件,默认执行rm *.log(字面删除名为“*.log”的文件);启用shopt -s failglob可让无匹配时报错中断,避免误操作 -
ls a?b匹配a1b、acb,但不匹配ab(? 必须对应一个字符)或a11b(? 只占一位) - 要匹配真实文件名中的特殊字符(如
*、?、[),需用反斜杠转义,如touch 'file\*.txt',之后用ls file\*.txt才能精确匹配
典型批量操作场景与写法示例
掌握组合技巧,能安全高效完成日常任务:
- 清理某类日志:
rm /var/log/app/*.log.2024-06-*(匹配 6 月所有带日期后缀的归档日志) - 重命名一批图片:
for f in IMG_*.JPG; do mv "$f" "${f%.JPG}.jpg"; done(注意引号防空格,%去后缀) - 统计特定代码行数:
wc -l *.py */*.py | grep -v "total$"(匹配当前及子目录所有 .py 文件) - 打包非临时文件:
tar -czf src.tgz !(temp|build)/(需先启用扩展:shopt -s extglob)
和正则表达式的本质区别
别混淆 glob 和 regex:前者是 shell 层的文件名生成,后者是命令(如 grep、sed)内部的文本内容匹配规则。
-
ls *.c→ shell 展开成main.c utils.c,再执行ls main.c utils.c -
grep "int.*main" *.c→ 先 glob 展开*.c,再对每个文件内容用正则int.*main搜索 -
find . -name "*.log"中的*.log是find自己接受的 shell glob 模式(-name参数定义),不是正则;要用正则得换-regex,且语法不同(如.*\.log)










