这适用于 bash:
touch a b c
echo !(a)
Run Code Online (Sandbox Code Playgroud)
如果我在 zsh 中执行上面的脚本(kshglob打开),它会抱怨:
zsh: number expected
Run Code Online (Sandbox Code Playgroud)
如果我在|之后添加a,它会起作用:
echo !(a|)
Run Code Online (Sandbox Code Playgroud)
为什么?
Sté*_*las 12
因为在这种情况下,它与裸 glob 限定符冲突,因为它位于模式的末尾。*(a1)取为最后一天访问的文件。(a1)被视为全局限定符。因此,在您的!(a)情况下, zsh 抱怨aglob 限定符(此处应用于名为 的文件!)后缺少天数。
在zshglobs 中,(...)分组主要用于(foo|bar)交替,因此添加 a|是一种记录方式,以确保尾随(...)不被视为 glob 限定符。
另一个记录在案的替代方法是将括号 ( !((a)))加倍,或者您可以添加一个空的 glob 限定符(如!(a)(-))。
要完全消除这种歧义,可以关闭bare_glob_qual选项 ( set +o bareglobqual),之后必须使用extendedglob (#q...)语法 ( *(#qa1)here)编写 glob 限定符。
该kshglob选项(在 1998 年添加,大致在同一时间bash添加,extglob尽管 bash 在此之前没有任何扩展的 glob)主要用于ksh仿真模式 ( emulate ksh),以便zsh能够运行ksh脚本,其中kshglob启用和bareglobqual禁用。首次引入时,启用 后kshglob,您需要指定 glob 限定符-(...)以避免这种冲突,但这会导致过多的混淆并与、和选项的@-(...)语法冲突。ksh93(#q...)bareglobqual
zsh用户一般都喜欢的zsh自己的扩展水珠(set -o extendedglob)运算符它们更容易输入(大多数)和更强大的(除启用了ksh88者kshglob中也发现bash -O extglob)。
例如,!(foo)会写成^foo. !(foo|)bar然而,等价物会更长,如(^(foo|))bar.
其他 ksh88 -> zsh 翻译:
*(x) -> x#+(x) -> x##@(x|y) -> x|y?(x) -> (x|)一些 ksh93 -> zsh 翻译:
~(i:x)-> (#i)x(不区分大小写)~(N)x-> x(N)(nullglob,起源于zsh){1,5}(x) -> x(#c1,5)@(foo&bar)->foo~^bar或^(^foo|^bar)有些只在zsh:
<1-23> (十进制数的范围)pattern~exceptpattern(glob-qualifier) (zsh globs 的杀手锏)(pattern/)#(匹配pattern; 的任何级别的子目录最近也添加到 ksh93 和 bash的**/简化版本(*/)#)***/* (符号链接后的递归通配符)。(#a1)foobar (近似匹配,允许一些错误,这里1)