19.2. 通配
Bash本身没有正则表达式的功能.在脚本里,使用正则表达式的是命令和软件包 -- 例如sed和awk-- 它们可以解释正则表达式.
Bash所做的是展开文件名扩展 [1]-- 这就是所谓的通配(globbing) -- 但它不是使用标准的正则表达式. 而是使用通配符. 通配解释标准的通配符:*和?, 方括号括起来的字符,还有其他的一些特殊的字符(比如说^用来表示取反匹配).然而通配机制的通配符有很大的局限性. 包含有*号的字符串将不会匹配以点开头的文件,例如.bashrc. [2]另外,通配机制的?字符和正则表达式中表示的意思不一样.
bash$ ls -l total 2 -rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1 -rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1 -rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1 -rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh -rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
bash$ ls -l t?.sh-rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh
bash$ ls -l [ab]*-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1
bash$ ls -l [a-c]*-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 a.1-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1
bash$ ls -l [^ab]*-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1-rw-rw-r-- 1 bozo bozo 466 Aug 6 17:48 t2.sh-rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
bash$ ls -l {b*,c*,*est*}-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 b.1-rw-rw-r-- 1 bozo bozo 0 Aug 6 18:42 c.1-rw-rw-r-- 1 bozo bozo 758 Jul 30 09:02 test1.txt
Bash会对命令行中没有引号引起来的字符尝试文件名扩展. echo命令可以印证这一点.
bash$ echo * a.1 b.1 c.1 t2.sh test1.txt
bash$ echo t*t2.sh test1.txt
可以改变Bash对通配字符进行解释的行为. set -f命令可以禁止通配机制, 并且shopt的选项nocaseglob和nullglob能改变通配的行为.
参考例子 10-4.
注
文件名扩展意思是扩展包含有特殊字符的文件名模式和模板. 例如,example.???可能扩展成example.001和/或example.txt.
文件名扩展能匹配点开头的文件,但仅在模式字串明确地包含字面意思的点(.)时才扩展.
1 ~/[.]bashrc # 不会扩展成 ~/.bashrc 2 ~/?bashrc # 也不会扩展. 3 # 通配机制中的通配符和元字符不会扩展点文件 4 # 5 6 ~/.[b]ashrc # 会扩展成 ~/.bashrc 7 ~/.ba?hrc # 也会. 8 ~/.bashr* # 也会. 9 10 # 可以使用"dotglob"选项把这个特性禁用. 11 12 # 多谢, S.C.