# 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
文件。