在linux的shell中,[] {}两种通配符很容易被混淆,这两种通配符虽然都是括号形式,但使用的场景和内容的解释方式都有所不同。
[ ] 只能用于匹配文件名的场景,而且[ ]内的字符只有两种解释方式:
- 当[ ]内部是两个用短横线“-”连接的正序的单个字符(如[5-9],[a-z]),指令将匹配含有这两个字符之间(包括这两个字符)的所有字符的文件名。
ls file[0-9]
上述指令将会使linux系统列出磁盘上所有符合格式的文件(即文件名为file0或file1或file2或file3……或file9的文件)。
-
当[ ]内部结构不能同时满足上述三个条件(用短横线连接、正序、单个字符),指令将会把[ ]内的每一个字符都当作无关系的单个字符看待。
ls file[1-10] ls file[1..9] ls file[1,4,5]
指令①ls file[1-10],将会匹配文件 file1 file- file0
指令②ls file[1..9], 将会匹配文件 file1 file. file9
指令③ls file[1,4,5],将会匹配文件 file1 file, file4 file5
{ } 无特定使用场景,但通常用于生成序列文件。在指令中使用{ }通配符,shell会先把{ }的内容按照解释方式翻译成一个或多个参数,再执行该含有多参数的指令。{ }内的字符有三种具有优先级的解释方式,按照优先级由高到低排列,分别如下:
- 当{ }内部含有逗号","时,shell将会按照逗号把括号内的内容分割成几个字符串。
touch file{1,2,3} touch file1 file2 file3 cp file{,.bak} cp file file.bak
指令①与②等价,指令③与④等价。值得注意的是,当逗号分隔出的某个区间为空时(指令③),依旧按照正则表达式被解释为一个参数。指令③常常用于备份文件的创建。
- 当{ }内部含有两个连续的小数点".."时,shell将会尝试将之解释为序列。
1)括号内部是由".."连接的两个数字时(不一定为单个字符,比如可以为11,353,4694等等),shell会将之解释为这两个数字和其中间所有数字所组成的参数序列,比如,下列三条指令是等价的:touch file{11..8} touch file{8..11} touch file8 file9 file10 file11
2)括号内部是由".."连接的两个字符时(必须为单个字符),shell会将之解释为在ASCII码表中这两个字符和其中间所有字符所组成的参数序列。值得注意的是,当其中一个字符为逗号","时,将按照优先级顺序,以1中的解释方式翻译。比如,下列第1、2和第3、4条指令分别是等价的:
touch file{,..?} touch file file..? touch file{,..3} touch file file..3
3)当括号内部虽然含有"..",却不满足上述两种格式,shell将不把它解释为序列,而是将{xx..xx}作为一个整体接受为指令的一个参数,即按照下边的第三种解释方式解释。
-
当括号内部不含有",",也不满足".."的两种序列格式,shell将不对其进行翻译,而是将大括号及其内容作为一个整体看待。
touch file{3fadf} touch file{aa..zz} touch file{}
以上三条指令分别会创建文件"file{3fadf}",文件"file{aa..zz}"和文件"file{}"。