Dividindo um caminho para um nome de arquivo [fechado]

1

No meu script zsh, gostaria de descobrir se meu diretório de trabalho começa com /cygdrive/?/... ou corresponde exatamente a /cygdrive/? (onde a letra da unidade (?) pode ser qualquer letra diferente da letra c) e se isso acontecer, recupere em duas variáveis a parte /cygdrive/? e a% restante/.... Exemplo: se meu diretório de trabalho for /cygdrive/r/abc/xyz , gostaria de ter a variável head definida como /cygdrive/r e a variável tail definida como /abc/xyz . Se o PWD for apenas, digamos, /cygdrive/r , a variável tail deverá estar vazia.

Eu prefiro uma solução usando apenas comandos internos zsh, ou seja, sem a necessidade de gerar um processo.

Eu criei a seguinte solução, que faz o trabalho, mas não gosto:

if [[ $PWD == /cygdrive/[abd-z]* ]]
then
  local head=${PWD:0:11}
  local tail=${PWD#/cygdrive/?}
  ....
fi
Em particular, eu não gosto do cálculo da cabeça, com o valor codificado de 11, e eu estou querendo saber se poderia haver uma abordagem completamente diferente, o que seria mais elegante.

UPDATE: estou ciente de que minha condição if também seria verdadeira, se o PWD for, por exemplo, /cygdrive/foo , mas, para meu aplicativo, não considero isso um problema. É claro que se você puder sugerir uma alternativa melhor para escrever a condição, o que exatamente faz o que eu quero, agradeço qualquer comentário.

    
por user1934428 10.08.2018 / 14:10

2 respostas

5
if [[ $PWD =~ '^(/cygdrive/[abd-z])(.*)' ]]; then
  head=$match[1]
  tail=$match[2]
fi

Same with globs:

set -o extendedglob
if [[ $PWD = (#b)(/cygdrive/[abd-z])(*) ]]; then
  head=$match[1]
  tail=$match[2]
fi

As globs também têm a vantagem de usar a própria correspondência de padrão de zsh , em que d-z corresponde apenas a defghijklmnopqrstuvwxyz , enquanto =~ usaria as regexps do seu sistema, em que [d-z] pode corresponder muito mais (como é ou até mesmo sequências de caracteres como dzs em locais húngaros). Fazer um set -o rematchpcre faria com que =~ usasse o PCRE, o que é mais razoável a esse respeito.

Para não coincidir em /cygdrive/foo :

if [[ $PWD =~ '^(/cygdrive/[abd-z])(/.*)?$' ]]; then
  head=$match[1]
  tail=$match[2]
fi

Com globs:

set -o extendedglob
if [[ $PWD = (#b)(/cygdrive/[abd-z])(/*|) ]]; then
  head=$match[1]
  tail=$match[2]
fi
    
por 10.08.2018 / 16:44
2

Como você já sabe como buscar o sufixo de sua variável, pode removê-lo da variável para ter o prefixo:

if [[ $PWD == /cygdrive/[abd-z] ]]
then
  local tail=${PWD#/cygdrive/?}
  local head=${PWD%%$tail}
  ....
fi

Quanto à condição, você pode usar expressões regulares no Zsh:

if [[ $PWD =~ '^/cygdrive/[abd-z](/.*)?$' ]]
then
    tail=${PWD#/cygdrive/?}
    head=${PWD%%$tail}

    echo "head is $head"
    echo "tail is $tail"
else
    echo "no match"
fi
    
por 10.08.2018 / 14:24

Tags