在 Linux 日常运维中,你是不是经常需要批量操作文件?比如一次性删除所有.log 日志、找出所有以file 开头的文本文件、筛选出编号 1-5 的配置文件……
这些高效的批量操作,都离不开 glob 通配符!它是 Shell 自带的文件名匹配工具,简单好用却暗藏不少坑 —— 新手容易把它和正则表达式搞混,动不动就踩 “引号缺失”“大括号误用” 的雷。
今天这篇文章,就把 glob 通配符的常用符号、实操案例、避坑指南一次性讲透,看完就能上手,效率直接翻倍!
glob 通配符 是 Shell(比如 bash)用来 匹配文件名 / 目录名 的简化语法,作用是 “快速筛选出符合规则的文件”,不需要写复杂的脚本。
核心特点:
✅匹配对象是文件名:只针对文件 / 目录的名字,不处理文件内容;
✅由 Shell 直接解析:在执行命令前,Shell 会先把通配符替换成匹配的文件名,再执行命令;
✅语法简单易懂:常用符号就几个,组合起来能搞定大部分批量操作场景。
举个最简单的例子:
# 列出当前目录下所有.txt文件ls *.txt
这里的*就是 glob 通配符,作用是 “匹配任意长度的任意字符”。
glob 的常用符号就 5 个:
*、?、[] 、[^]、[-] ,每个符号都有明确的适用场景,搭配例子一看就会!
匹配任意长度的任意字符(0 个或多个)
* 是最常用的通配符,相当于 “万能钥匙”,可以匹配空字符、单个字符、多个字符。
实操案例
# 1. 匹配当前目录下所有.txt文件(文件名任意,后缀是txt)ls *.txt# 2. 匹配所有以file开头的文件(不管后缀是什么)ls file*# 3. 匹配所有包含log的文件(名字里有log就行,位置不限)ls *log*# 4. 匹配/var/log下所有以.log结尾的文件ls /var/log/*.log
注意点
🚨不能匹配以.开头的隐藏文件(比如.bashrc ),如果要匹配隐藏文件,需要写成 .*;🚨不会匹配路径分隔符/,所以a*b 不能匹配
匹配单个任意字符
? 和*的区别是:只能匹配一个字符,多了少了都不行。
实操案例
# 1. 匹配文件名是“任意单个字符+txt”的文件(比如a.txt、1.txt,不能是ab.txt)ls ?.txt# 2. 匹配以file开头,后面跟一个字符,后缀是log的文件(比如file1.log、filea.log)ls file?.log# 3. 匹配名字是3个字符的文件(比如abc、123,不能是abcd)ls ???
匹配范围内的单个字符
[ ] 用来指定一个字符范围,只匹配其中的一个字符,适合精准筛选。
常用范围写法
✅[abc] :匹配 a、b、c 中的任意一个字符;
✅[a-z] :匹配小写字母 a 到 z 中的任意一个;
✅[A-Z] :匹配大写字母 A 到 Z 中的任意一个;
✅[0-9] :匹配数字 0 到 9 中的任意一个;
✅[a-zA-Z0-9] :匹配字母和数字中的任意一个。
实操案例
# 1. 匹配file1.log、file2.log、file3.log(不包含file4.log)ls file[1-3].log# 2. 匹配以a、b、c开头的txt文件(比如a.txt、b.txt、c.txt)ls [abc].txt# 3. 匹配名字包含数字的文件(比如test1.txt、demo2.log)ls *[0-9]*
匹配范围外的单个字符
[^] 是 [ ] 的反向匹配,意思是 “不匹配括号内的字符”。
实操案例
# 1. 匹配file后面不是1-3的.log文件(比如file4.log、filea.log,排除file1-3.log)ls file[^1-3].log# 2. 匹配不是以a、b、c开头的txt文件ls [^abc].txt
有些 Shell(比如 zsh)中,反向匹配用!代替^,写成[!abc] ,效果一样。
简化字符范围
[-] 是[]的辅助符号,用来连接起始和结束字符,简化范围写法。
注意点
🚨如果-不在两个字符中间,它就不是通配符,而是普通字符;
🚨比如[a-z] 是范围,[az-] 匹配的是 a、z、- 这三个字符。
很多人用不好 glob,不是因为符号记不住,而是踩了 “混淆概念”“语法误用” 的坑,这 3 个误区一定要避开!
这是新手最容易犯的错!glob 和正则虽然都有*、[] 这样的符号,但 用途和语法完全不同,千万别搞混!
踩坑例子
# 错误用法:想用glob的*匹配文本内容里的“任意字符”grep "a*b" test.txt # 这里的*是正则符号,不是glob!# 本意是找包含a和b的行,结果匹配了所有包含b的行(a出现0次)# 正确区分:ls a*b.txt # glob:匹配文件名以a开头、b结尾的txt文件grep "a.*b" test.txt # 正则:匹配文本中a和b之间有任意字符的行
当你想把通配符作为普通字符传递给命令时,如果不加引号,Shell 会先把它解析成文件名,导致命令执行结果和预期不符!
踩坑例子
# 本意:想输出字符串“*.txt”echo *.txt# 实际输出:当前目录下所有.txt文件的名字(比如a.txt b.txt)# 正确用法:加单引号或双引号,让通配符变成普通字符echo "*.txt" # 输出:*.txtecho '*.txt' # 输出:*.txt
实用场景
用grep搜索包含*的文本时,必须加引号:
# 搜索test.txt中包含“*.txt”的行grep "*.txt" test.txt # 正确grep *.txt test.txt # 错误!Shell会把*.txt解析成文件名
很多人把{}当成 glob 的一部分,其实 大括号{} 是 bash 的大括号扩展,不是 glob 通配符!
两者的核心区别:
✅glob:匹配已存在的文件;
✅大括号扩展:生成新的字符串,不管文件是否存在。
踩坑例子
# 大括号扩展:生成file1.txt、file2.txt、file3.txt(不管文件是否存在)touch file{1..3}.txt# glob通配符:匹配已存在的file1-3.txt文件ls file[1-3].txt# 错误用法:用{}匹配已存在的文件ls file{1..3}.txt # 虽然能列出文件,但本质是先扩展成三个文件名,再执行ls# 如果文件不存在,ls会报错:无法访问file{1..3}.txt
关键提醒
🚨想生成一系列文件名:用大括号扩展{1..5} 、{a,b,c} ;
🚨想匹配已存在的文件名:用 glob 通配符*、?、[] 。
掌握了单个符号的用法,组合起来能实现更复杂的匹配需求!
组合案例
# 1. 匹配当前目录下,以file开头、数字结尾的.log文件ls file*[0-9].log# 2. 匹配/var/log下,不是以数字开头的.log文件ls /var/log/[^0-9]*.log# 3. 匹配名字是“字母+数字+字母”的3字符文件ls [a-zA-Z][0-9][a-zA-Z]
新手用 glob 时,不确定匹配的文件是否正确,可以先用echo 命令测试,避免误删文件!
# 测试要删除的文件是否正确echo *.log # 先看输出的文件名是不是你想删的rm *.log # 确认无误后再删除
✅核心符号:*任意字符、?单个字符、[]范围匹配、[^] 反向匹配;✅三大误区:别和正则搞混、别忘加引号、别把{} 当 glob;
✅实用技巧:先用echo 测试匹配结果,再执行rm等危险命令。
glob 通配符是 Linux 运维的效率神器,不用记复杂语法,只要掌握这几个符号和避坑要点,日常批量操作文件就能得心应手!
你在使用 glob 时踩过什么坑?评论区分享一下吧~