Intervalos multidigit de arquivos em ordem lexicográfica em zsh

17

Eu gostaria de especificar um intervalo de arquivos (em ordem lexicográfica) com dois inteiros (por exemplo, 2 a 57) em zsh por globbing.

Por exemplo: "escolha os arquivos 2 a 57 em ordem lexicográfica sob o caminho que corresponde a algum padrão de globbing".

Eu pensei que usar colchetes faria isso

 for x in /foo/bar/*[2-57]; do print $x; done

mas aparentemente o zsh está pedindo os arquivos 2 to 5 (ou algo parecido) em vez dos arquivos 2 to 57 . Alguma ideia do porquê? Como posso conseguir isso?

    
por Amelio Vazquez-Reina 19.11.2011 / 00:11

2 respostas

20

[2-57] é um conjunto de caracteres que consiste em 2 , 3 , 4 , 5 e 7 , em zsh e todas as outras sintaxes de caracteres curinga e expressões regulares no mercado. Seu padrão de glob *[2-57] corresponde a cada nome de arquivo cujo último caractere é um desses cinco dígitos.

Acho que você está se lembrando incorretamente da sintaxe do [m,n] qualificador da glob . Qualificadores de Glob sempre ficam entre parênteses no final do padrão, e o separador de intervalo é uma vírgula. O padrão *([2,57]) se expande para o 2º, 3º, ..., 57º. A ordem de expansão padrão é lexicográfica (com alguma mágica especial para classificar números em ordem numérica se a opção numeric_glob_sort estiver configurada); você pode controlá-lo com o qualificador o ou O glob (por exemplo, *(om[2,57]) para corresponder ao arquivo mais recente, exceto o arquivo mais recente).

for x in /foo/bar/*([2,57]); do print $x; done

Não é o que você pediu, mas relacionado e possivelmente útil para futuros leitores: se você quiser enumerar os arquivos 2 a 57, independentemente de existirem ou não, você pode usar um intervalo expressão de colchetes . Este recurso também existe em bash e ksh.

echo hello{2..57}

E se você quiser corresponder arquivos cujo nome contenha um número entre 2 e 57, use o padrão <2-57> . Isso é específico para zsh.

$ ls
file1 file2 file3 file57 file58
$ echo file<2-57>
file2 file3 file57

Observe que um padrão como *<2-57> provavelmente não fará o que você espera, porque o * também pode corresponder aos dígitos. Por exemplo, file58 corresponde a *<2-57> , com file5 correspondendo à parte * e 8 correspondendo à parte <2-57> . O padrão *[^0-9]<2-57> evita esse problema.

    
por 19.11.2011 / 02:37
6

but zsh apparently thinks I am asking for the files 2 to 5 (or something like that) instead of files 2 to 57. Any thoughts why?

Porque [] colchetes indicam uma lista de caracteres combinados (que podem ser dígitos), não números interpretados matematicamente. Esse padrão é comparado com um caractere único . A lista pode conter intervalos, mas de dígitos ou letras. [2-57] corresponde a "Todos os dígitos no intervalo de 2 a 5 e a 7" .

Para corresponder números de 2 a 57, seria mais fácil usar uma expressão de sequência em vez de um padrão de globbing (ou junto com isso):

for x in /foo/bar/*{2..57}; do print $x; done

Editar : Mas isso, infelizmente, não lhe dará uma ordem lexicográfica de todos os arquivos listados - eles seriam agrupados por términos numéricos comuns devido à expansão do shell.

    
por 19.11.2011 / 00:25

Tags