dedowsdi Asked: 2019-06-30 22:01:54 +0800 CST2019-06-30 22:01:54 +0800 CST 2019-06-30 22:01:54 +0800 CST 为什么即使我打开了 kshglob,我也不能在 zsh 中使用 !(single pattern)? 772 这在 bash 中有效: touch a b c echo !(a) 如果我在 zsh 中执行上面的脚本(kshglob打开),它会抱怨: zsh: number expected 如果我在|之后添加a,它可以工作: echo !(a|) 为什么? zsh wildcards 1 个回答 Voted Best Answer Stéphane Chazelas 2019-06-30T23:03:08+08:002019-06-30T23:03:08+08:00 因为在这种情况下,它与裸 glob 限定符冲突,因为它位于模式的末尾。*(a1)被视为最后一天访问的文件。(a1)被视为全局限定符。因此,在您的!(a)情况下, zsh 抱怨在aglob 限定符之后缺少天数(此处应用于名为 的文件!)。 在zshglob 中,(...)分组主要用于(foo|bar)交替,因此添加 a|是一种记录方法,以确保尾随(...)不被视为 glob 限定符。 另一个记录在案的替代方法是将括号 ( ) 加倍,!((a))或者您可以添加一个空的 glob 限定符(如!(a)(-))。 要完全消除这种歧义,可以关闭bare_glob_qual选项 ( set +o bareglobqual),之后必须使用extendedglob (#q...)语法 (*(#qa1)此处 ) 编写全局限定符。 该kshglob选项(在 1998 年添加,大致在同一时间bash添加,extglob虽然 bash 在此之前没有任何扩展的 glob)主要用于ksh仿真模式(emulate ksh),以便zsh能够运行ksh脚本,在哪里kshglob启用和bareglobqual禁用。首次引入时,在启用后kshglob,您需要指定 glob 限定符-(...)以避免这种冲突,但这会导致太多混乱并与 的@-(...)语法相冲突ksh93,(#q...)andbareglobqual选项是稍后引入的。 zsh用户通常更喜欢 zsh 自己的扩展 glob ( ) 操作符,这些操作符更容易输入(对于大多数人来说)并且更强大(比在 中也可以找到set -o extendedglob的 ksh88 操作符)。kshglobbash -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~except pattern(glob-qualifier)(zsh glob 的杀手级功能) (pattern/)#pattern(与;匹配的任何级别的子目录最近也添加到 ksh93 和 bash 中**/)(*/)# ***/*(符号链接后的递归通配符)。 (#a1)foobar(近似匹配,允许一些错误,这里是1) ...
因为在这种情况下,它与裸 glob 限定符冲突,因为它位于模式的末尾。
*(a1)
被视为最后一天访问的文件。(a1)
被视为全局限定符。因此,在您的!(a)
情况下, zsh 抱怨在a
glob 限定符之后缺少天数(此处应用于名为 的文件!
)。在
zsh
glob 中,(...)
分组主要用于(foo|bar)
交替,因此添加 a|
是一种记录方法,以确保尾随(...)
不被视为 glob 限定符。另一个记录在案的替代方法是将括号 ( ) 加倍,
!((a))
或者您可以添加一个空的 glob 限定符(如!(a)(-)
)。要完全消除这种歧义,可以关闭
bare_glob_qual
选项 (set +o bareglobqual
),之后必须使用extendedglob
(#q...)
语法 (*(#qa1)
此处 ) 编写全局限定符。该
kshglob
选项(在 1998 年添加,大致在同一时间bash
添加,extglob
虽然 bash 在此之前没有任何扩展的 glob)主要用于ksh
仿真模式(emulate ksh
),以便zsh
能够运行ksh
脚本,在哪里kshglob
启用和bareglobqual
禁用。首次引入时,在启用后kshglob
,您需要指定 glob 限定符-(...)
以避免这种冲突,但这会导致太多混乱并与 的@-(...)
语法相冲突ksh93
,(#q...)
andbareglobqual
选项是稍后引入的。zsh
用户通常更喜欢 zsh 自己的扩展 glob ( ) 操作符,这些操作符更容易输入(对于大多数人来说)并且更强大(比在 中也可以找到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~except
pattern(glob-qualifier)
(zsh glob 的杀手级功能)(pattern/)#
pattern
(与;匹配的任何级别的子目录最近也添加到 ksh93 和 bash 中**/
)(*/)#
***/*
(符号链接后的递归通配符)。(#a1)foobar
(近似匹配,允许一些错误,这里是1)