Это работает в Bash:
touch a b c
echo !(a)
Если я выполняю вышеупомянутый скрипт в zsh (с kshglob
on), он жалуется:
zsh: number expected
Если я добавлю |
после a
, это работает:
echo !(a|)
Почему?
Потому что в этом случае он конфликтует с пустыми глобальными квалификаторами, поскольку находится в конце шаблона. *(a1)
берется как файлы, к которым последний раз обращались в последний день. (a1)
рассматривается как глобус квалификатор. Так что в вашем !(a)
случае zsh жалуется на пропущенное количество дней после a
квалификатора glob (здесь применяется к названному файлу !
).
В zsh
globs (...)
группирование в основном используется для (foo|bar)
чередования, поэтому добавление |
является документированным способом убедиться, что трейлинг (...)
не рассматривается как квалификатор glob.
Другая документированная альтернатива - удвоить скобки ( !((a))
), или вы можете добавить пустой спецификатор glob (например !(a)(-)
).
Чтобы полностью устранить эту неоднозначность, можно отключить bare_glob_qual
параметр ( set +o bareglobqual
), после которого необходимо написать квалификатор glob с extendedglob
(#q...)
синтаксисом ( *(#qa1)
здесь).
kshglob
Вариант ( добавлена в 1998 году , примерно в то же время bash
добавил его extglob
хотя баш не было никакого расширенного Glob до этого) в основном там для ksh
режима эмуляции ( emulate ksh
), для zsh
чтобы иметь возможность запускать ksh
скрипты, где kshglob
включен и bareglobqual
выключен. Когда он был впервые представлен, после включения kshglob
вам нужно было указать спецификаторы глобуса, -(...)
чтобы избежать такого рода конфликтов, но это вызвало слишком большую путаницу и противоречило @-(...)
синтаксису ksh93
, (#q...)
а bareglobqual
параметры и были представлены позже.
zsh
пользователи обычно предпочитают собственные расширенные set -o extendedglob
операторы glob ( ) в zsh, которые легче вводить (для большинства) и более мощные (чем 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 Globs)(pattern/)#
(любой уровень подкаталогов, соответствующих pattern
; **/
упрощенная версия (*/)#
также была добавлена в ksh93 и bash недавно)***/*
(рекурсивное сглаживание по символическим ссылкам).(#a1)foobar
(приблизительное соответствие, допускающее некоторые ошибки, здесь 1)