Isso funciona no bash:
touch a b c
echo !(a)
Se eu executar o script acima no zsh (com kshglob
on), ele reclama:
zsh: number expected
Se eu adicionar |
depois a
, ele funciona:
echo !(a|)
Por quê?
Porque nesse caso, ele entra em conflito com os qualificadores de globos simples, pois está no final do padrão. *(a1)
é obtido como os arquivos acessados pela última vez no último dia. (a1)
é tratado como um qualificador glob. Portanto, no seu !(a)
caso, o zsh reclama do número de dias que faltam após o a
qualificador glob (aqui aplicado ao arquivo chamado !
).
Nos zsh
globos, o (...)
agrupamento é usado principalmente para a (foo|bar)
alternância, portanto, adicionar a |
é uma maneira documentada de garantir que uma trilha (...)
não seja tratada como um qualificador glob.
Outra alternativa documentada é dobrar os parênteses ( !((a))
) ou você pode adicionar um qualificador de glob vazio (como !(a)(-)
).
Para remover completamente essa ambiguidade, é possível desativar a bare_glob_qual
opção ( set +o bareglobqual
), após a qual os qualificadores globais precisam ser escritos com a extendedglob
(#q...)
sintaxe ( *(#qa1)
aqui).
A kshglob
opção ( adicionado em 1998 , aproximadamente o mesmo tempo bash
adicionado a sua extglob
festa, embora não tinha qualquer glob estendida antes disso) é principalmente lá para o ksh
modo de emulação ( emulate ksh
), para zsh
ser capaz de executar ksh
scripts onde kshglob
está ativado e bareglobqual
está desativada. Quando foi introduzido pela primeira vez, após a ativação kshglob
, você precisaria especificar qualificadores globais -(...)
para evitar esse tipo de conflito, mas isso causou muita confusão e entrou em conflito com a @-(...)
sintaxe de ksh93
, as opções (#q...)
e bareglobqual
foram introduzidas mais tarde.
zsh
os usuários geralmente preferem os set -o extendedglob
operadores glob ( ) estendidos do zsh, que são mais fáceis de digitar (para a maioria) e mais poderosos (do que os ksh88 habilitados com kshglob
também encontrados em bash -O extglob
).
Por exemplo, !(foo)
seria escrito ^foo
. O !(foo|)bar
equivalente seria, no entanto, mais longo (^(foo|))bar
.
Outras traduções para ksh88 -> zsh:
*(x)
-> x#
+(x)
-> x##
@(x|y)
-> x|y
?(x)
-> (x|)
Algumas traduções para ksh93 -> zsh:
~(i:x)
-> (#i)x
(sem distinção entre maiúsculas e minúsculas)~(N)x
-> x(N)
(nullglob, originado em zsh){1,5}(x)
-> x(#c1,5)
@(foo&bar)
-> foo~^bar
ou^(^foo|^bar)
Alguns só foram encontrados em zsh
:
<1-23>
(intervalo de números decimais)pattern~except
pattern(glob-qualifier)
(o recurso matador de zsh globs)(pattern/)#
(qualquer nível de subdiretórios que corresponda ao pattern
; a **/
versão simplificada do (*/)#
também foi adicionada ao ksh93 e bash recentemente)***/*
(globbing recursivo após links simbólicos).(#a1)foobar
(correspondência aproximada, permitindo alguns erros, aqui 1)