Correspondência de padrões em uma expressão condicional zsh

Correspondência de padrões em uma expressão condicional zsh

Estou tendo problemas com a correspondência de padrões na função de gancho do zsh precmd. Eu tenho o seguinte:

precmd(){
   local x='test'
   if [ $x = '*test*' ]; then
      echo 'hello'
   fi
}

que nunca imprime olá. Eu testei esse código com um normal zsh test.zshque funciona bem, tentei sem o regex precmde consegui imprimir as coisas também. Alguma pista de por que isso não está funcionando como esperado?

$ zsh --version
zsh 4.3.11 RHEL 

Responder1

[ $x = '*test*' ]testa se a string resultante da expansão $x, que é text, é igual à string resultante da expansão '*test*', que é *text*.

Para testar se o valor da variável xcorresponde aopadrão *test*, você precisa usar o operador =ou ==deexpressões condicionais zsh, que estão escritos dentrocolchetes duplos [[ … ]]. Além disso, os caracteres especiais no padrão não devem estar entre aspas, caso contrário, eles serão independentes. Por isso:

if [[ $x == *test* ]]; then …

A sintaxe das expressões condicionais é semelhante à sintaxe das expressões que você pode usar entre colchetes simples [ … ], mas não idêntica. [é analisado como um comando comum; na verdade, é um comando integrado com um nome de um caractere, que é idêntico aotestconstruídas emexceto que isso [requer um argumento adicional no final, que deve ser ]. [[ … ]]é uma construção gramatical distinta, que permite conter caracteres especiais do shell. [ $x = *test* ]expandiria *test*para a lista de nomes de arquivos correspondentes (globbing) e o testbuiltin acabaria analisando o resultado disso. [[ $x = *test* ]]analisa *test*como parte da análise de expressão condicional que não invoca globbing.

Responder2

*test*não é um padrão regex válido. O *é um operador de repetição e precisa de algo para repetir. É muito provável que você queira .*test.*, embora isso não seja necessário com regex, pois não está ancorado por padrão. Você poderia apenas procurartest

No entanto, você não pode combinar padrões regex com o =operador, você precisa do =~.

precmd () {
   local x=test
   if [[ $x =~ test ]]; then
      echo 'hello'
   fi
}

informação relacionada