KSH Padrão da variável não funciona

1

Alguém poderia me explicar por que o padrão no shell Korn (atribuído à variável) funciona dessa maneira:

u@h:w$ pattern='file_[0-9][0-9]'
u@h:w$ ls $pattern
file_01  file_02  file_03

Mas não funciona para um padrão mais inteligente file_{2}([0-9]) :

$ pattern='file_{2}([0-9])'
$ ls $pattern
ls: file_{2}([0-9]): No such file or directory
    
por Kamil 01.12.2016 / 14:17

1 resposta

4

Isso é intencional, para evitar quebrar a conformidade com POSIX (embora inicialmente tenha sido para evitar a quebra da compatibilidade com o Bourne).

echo file_{2}([0-9])

seria um código inválido em Bourne / POSIX sh , portanto, ksh está livre para interpretá-lo como quiser. Mas:

pattern='file_{2}([0-9])'
echo $pattern

é válido como código Bourne / POSIX sh e, conforme POSIX, deve corresponder aos arquivos nomeados como file_{2}(0) , file_{2}(1) ...

Os operadores estendidos não estão disponíveis quando eles são o resultado de uma expansão, mesmo se você usar:

echo @($pattern)

Você precisaria usar eval ou também poderia usar FIGNORE :

FIGNORE="!($pattern)"; echo *

(cuidado, porém, isso afeta a expansão de arquivos ocultos, torne-o FIGNORE="@(.*|!($pattern))" se você não espera que o glob expanda arquivos ocultos).

Observe que bash e zsh adotaram alguns desses ksh de operadores estendidos (embora não o {x,y}(...) one), mas eles abordaram a compatibilidade do POSIX / Bourne de maneira diferente: eles disponibilizam esses globs estendidos em todos contextos, mas somente quando uma opção específica é ativada ( kshglob in zsh , extglob in bash ). Isso significa, no entanto, que é difícil para eles adicionar mais operadores sem quebrar sua própria compatibilidade com versões anteriores. Por exemplo, se bash adicionasse o operador {x,y}(...) agora, ele poderia quebrar os scripts que esperam que a='{1}(2){3}'; [[ $a = $a ]] retorne verdadeiro.

    
por 01.12.2016 / 14:40