# 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
1
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
1
2
3
4
5
6
7

上面代码中,如果不存在 a.txtb.txt,那么 [ab].txt 就会变成一个普通的文件名,而 {a,b}.txt 可以照样展开。

大括号可以嵌套也可以与其他模式联用。

echo {j{p,pe}g,png}

echo {cat, d*}
1
2
3

上面代码中,会先进行大括号扩展,然后进行 * 扩展。

# 6 {start...end}

{start..end} 会匹配连续范围的字符。

echo d{a..d}g

echo {11..15}
1
2
3

遇到无法解释的 pattern 会原样输出。

echo {a1..3c}
1

{} 与逗号联用,可以写出复杂的模式:

echo {mp{3..4},mp{a,b,p,v}}

1
2

# 7 注意点

(1)通配符是先解释,再执行。

(2)匹配子目录里的文件写法。

$ ls */*.txt

** 匹配 0 或更多的目录。

/**/a 匹配 /b/a /c/d/a /a 匹配所有 a 文件夹。

/a/**/b/ 匹配所有 a 为上层目录,b 为下层目录的情况。

a/**/* 匹配 a 路径下所有文件和子文件,包括目录。

/**/*.x 匹配任何的 .x 文件。

# 8 参考链接

阮一峰-命令行通配符教程 (opens new window)

参考 (opens new window)

最后更新: 2023/4/4 11:22:15