Por que não consigo usar! (Padrão único) no zsh mesmo depois de ativar o kshglob?

8

Isso funciona no bash:

touch a b c
echo !(a)

Se eu executar o script acima no zsh (com kshglobon), ele reclama:

zsh: number expected

Se eu adicionar |depois a, ele funciona:

echo !(a|)

Por quê?

dedowsdi
fonte

Respostas:

10

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 aqualificador glob (aqui aplicado ao arquivo chamado !).

Nos zshglobos, 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_qualopção ( set +o bareglobqual), após a qual os qualificadores globais precisam ser escritos com a extendedglob (#q...)sintaxe ( *(#qa1)aqui).

A kshglobopção ( adicionado em 1998 , aproximadamente o mesmo tempo bashadicionado a sua extglobfesta, embora não tinha qualquer glob estendida antes disso) é principalmente lá para o kshmodo de emulação ( emulate ksh), para zshser capaz de executar kshscripts onde kshglobestá ativado e bareglobqualestá 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 bareglobqualforam introduzidas mais tarde.

zshos usuários geralmente preferem os set -o extendedgloboperadores glob ( ) estendidos do zsh, que são mais fáceis de digitar (para a maioria) e mais poderosos (do que os ksh88 habilitados com kshglobtambém encontrados em bash -O extglob).

Por exemplo, !(foo)seria escrito ^foo. O !(foo|)barequivalente 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~^barou^(^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)
  • ...
Stéphane Chazelas
fonte