在 Bash 中,要进行负文件通配,我有以下 2 个选择。他们之间有区别吗?两者返回相同的结果:
$ ls
f1.txt f2.txt f3.txt f4.txt
$ ls f[!24]*
f1.txt f3.txt
$ ls f[^24]*
f1.txt f3.txt
答案1
该[!...]
模式匹配不属于...
方括号内的字符集的单个字符。这是 POSIX shell 使用的文件名通配模式。
该[^...]
模式的工作原理相同,但它是 POSIX 正则表达式。此模式通常不能作为文件名通配模式移植到其他 shell,但bash
shell 会识别它并将其视为与该[!...]
模式相同。
如果您在编写文件名通配模式时可以在这两者之间进行选择,那么您很可能应该使用可移植的 POSIX 变体[!...]
。
POSIX 标准说关于文件名通配模式的[...]
一般情况:
如果开括号引入了如 XBD RE 括号表达式中那样的括号表达式,除了字符
<exclamation-mark>
(!
) 应替换正则表达式表示法中非匹配列表中的<circumflex>
字符 ( ) 之外,它应引入模式括号表达式。^
以不带引号的字符开头的括号表达式<circumflex>
会产生未指定的结果。否则,[
应匹配字符本身。
“XBD RE 括号表达式”是[...]
正则表达式的规范。
[^...]
该标准将文件名通配模式中的使用保留为“未指定”,并且bash
shell(以及其他一些)选择将其实现为与[!...]
.