# 1 ? 字符
 ? 匹配单个字符,匹配多个字符,需要多个 ? 连用。? 不能匹配空字符。
# 2 * 字符
 * 匹配任意数量的字符,可以匹配空字符。
ls * 列出所有文件
# 3 [...] 模式
 [...] 匹配方括号中的任意一个字符,[start-end] 表示一个连续的范围,如 [1-9]、[a-z]。
只能用于匹配文件名的场景.
- 当
[]内部是两个用短横线“-”连接的正序的单个字符(如[5-9],[a-z]),指令将匹配含有这两个字符之间(包括这两个字符)的所有字符的文件名。 - 内部结构不能同时满足上述三个条件(用短横线连接、正序、单个字符),指令将会把
[ ]内的每一个字符都当作无关系的单个字符看待。 
ls file[1-10]
ls file[1..9]
ls file[1,4,5]
ls file[245].c
 2
3
4
# 4 [^...] 和 [!...]
 匹配不在方括号里面的字符(不包括空字符)。也可以使用连续写法:[!1-9]。
# 5 {...}
 无特定使用场景,但通常用于生成序列文件。在指令中使用{ }通配符,shell会先把{ }的内容按照解释方式翻译成一个或多个参数,再执行该含有多参数的指令。
匹配{} 内所有模式,模式之间用 , 分隔。
{...} 和 [...] 的区别是:如果匹配的文件不存在,[...] 会失去模式的功能,变成一个单纯的字符串,而 {...} 依然可以展开。
内部含有逗号","时,shell将会按照逗号把括号内的内容分割成几个字符串。
内部含有两个连续的小数点".."时,shell将会尝试将之解释为序列。
当括号内部不含有",",也不满足".."的两种序列格式,shell将不对其进行翻译,而是将大括号及其内容作为一个整体看待
如:
# 不存在 a.txt 和 b.txt
$ ls [ab].txt
ls: [ab].txt: No such file or directory
$ ls {a,b}.txt
ls: a.txt: No such file or directory
ls: b.txt: No such file or directory
 2
3
4
5
6
7
上面代码中,如果不存在 a.txt 和 b.txt,那么 [ab].txt 就会变成一个普通的文件名,而 {a,b}.txt 可以照样展开。
大括号可以嵌套也可以与其他模式联用。
echo {j{p,pe}g,png}
echo {cat, d*}
 2
3
上面代码中,会先进行大括号扩展,然后进行 * 扩展。
# 6 {start...end}
 {start..end} 会匹配连续范围的字符。
echo d{a..d}g
echo {11..15}
 2
3
遇到无法解释的 pattern 会原样输出。
echo {a1..3c}
 {} 与逗号联用,可以写出复杂的模式:
echo {mp{3..4},mp{a,b,p,v}}
 2
# 7 注意点
(1)通配符是先解释,再执行。
(2)匹配子目录里的文件写法。
$ ls */*.txt
** 匹配 0 或更多的目录。
/**/a 匹配 /b/a /c/d/a /a 匹配所有 a 文件夹。
/a/**/b/ 匹配所有 a 为上层目录,b 为下层目录的情况。
a/**/* 匹配 a 路径下所有文件和子文件,包括目录。
/**/*.x 匹配任何的 .x 文件。