Intervalos de arquivos com vários dígitos em ordem lexicográfica no zsh
24
Eu gostaria de especificar um intervalo de arquivos (em ordem lexicográfica) com dois números inteiros (por exemplo, 2 a 57) no zsh por meio de globbing.
Por exemplo: "escolha os arquivos de 2 a 57 em ordem lexicográfica no caminho que corresponda a algum padrão de globbing".
Eu pensei que usando colchetes faria isso
for x in/foo/bar/*[2-57];do print $x;done
mas zsh aparentemente pensa que eu estou pedindo para os arquivos 2para 5(ou algo parecido) em vez de arquivos 2para 57. Alguma idéia do porquê? Como posso fazer isso?
[2-57]é um conjunto de caracteres consistindo de 2, 3, 4, 5e 7, em zsh e qualquer outro wildcard e sintaxe regexp lá fora. Seu padrão glob *[2-57]corresponde a todos os nomes de arquivos cujo último caractere é um desses cinco dígitos.
Eu acho que você está se lembrando mal da sintaxe do [m,n]qualificador glob . Os qualificadores de globos sempre aparecem entre parênteses no final do padrão, e o separador de intervalo é uma vírgula. O padrão se *([2,57])expande para a 2ª, 3ª,…, 57ª correspondências. A ordem de expansão padrão é lexicográfica (com alguma mágica especial para classificar números em ordem numérica, se a numeric_glob_sortopção estiver configurada); você pode controlá-lo com o qualificador oou Oglob (por exemplo, *(om[2,57])para corresponder ao 57 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, se eles existem ou não, é possível usar uma expressão de intervalo entre chaves . Esse recurso também existe no bash e no ksh.
echo hello{2..57}
E se você deseja combinar arquivos cujo nome contém um número entre 2 e 57, você pode usar o padrão <2-57>. Isso é específico para o zsh.
Observe que um padrão como *<2-57>provavelmente não faz o que você espera, porque também *pode corresponder a dígitos. Por exemplo, file58corresponde *<2-57>, com a file5correspondência da *parte e 8a <2-57>parte. O padrão *[^0-9]<2-57>evita esse problema.
Você está certo. Eu estava me lembrando do qualificador da glob. Obrigado pela explicação cuidadosa.
Amelio Vazquez-Reina
By the way, esta declaração me deixou um pouco confuso: if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. Se os arquivos não existirem e não houver correspondências, como a expansão de chaves saberia como expandir? (como seria expandir de forma diferente do qualificador glob?)
Amelio Vazquez-Reina
2
@intrpc foo{8..11}barexpande para foo8bar foo9bar foo10bar foo11bar. Esse pouco de expansão não está relacionado aos nomes dos arquivos. Da mesma forma, foo{eight,nine,ten,eleven}barexpande para fooeightbar fooninebar footenbar fooelevenbar. Isso é expansão de chaves em ksh / bash / zsh.
Gilles 'SO- stop be evil'
6
mas o zsh aparentemente pensa que estou pedindo os arquivos 2 a 5 (ou algo parecido) em vez dos arquivos 2 a 57. Alguma idéia do porquê?
Como []colchetes indicam uma lista de caracteres correspondentes (que podem ser dígitos), não números interpretados matematicamente. Esse padrão é comparado com um único caractere. A lista pode conter intervalos, mas de dígitos ou letras. [2-57]A correspondência se expande para "Todos os dígitos no intervalo de 2 a 5 e 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
Edit : Mas isso, infelizmente, não fornecerá a ordem lexicográfica de todos os arquivos listados - eles serão agrupados por terminações de números comuns devido à expansão do shell.
Obrigado @rozcietrzewiacz! Eu deveria ter pensado nisso. Meus arquivos tinham números neles, então, por um momento eu pensei que []estava imprimindo as coisas em ordem ..
Amelio Vazquez-Reina
Sua explicação [2-57]está correta, mas eu não acho {2..57}(é isso que você quis dizer, certo?) É relevante para o que a intrpc deseja fazer, que é "escolher os arquivos de 2 a 57 em ordem lexicográfica".
Gilles 'SO- stop be evil'
Obrigado pela edição (hora de dormir, eu acho). E você está certo - eu tinha esquecido a parte da ordem lexicográfica .
if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression
. Se os arquivos não existirem e não houver correspondências, como a expansão de chaves saberia como expandir? (como seria expandir de forma diferente do qualificador glob?)foo{8..11}bar
expande parafoo8bar foo9bar foo10bar foo11bar
. Esse pouco de expansão não está relacionado aos nomes dos arquivos. Da mesma forma,foo{eight,nine,ten,eleven}bar
expande parafooeightbar fooninebar footenbar fooelevenbar
. Isso é expansão de chaves em ksh / bash / zsh.Como
[]
colchetes indicam uma lista de caracteres correspondentes (que podem ser dígitos), não números interpretados matematicamente. Esse padrão é comparado com um único caractere. A lista pode conter intervalos, mas de dígitos ou letras.[2-57]
A correspondência se expande para "Todos os dígitos no intervalo de 2 a 5 e 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):
Edit : Mas isso, infelizmente, não fornecerá a ordem lexicográfica de todos os arquivos listados - eles serão agrupados por terminações de números comuns devido à expansão do shell.
fonte
[]
estava imprimindo as coisas em ordem ..[2-57]
está correta, mas eu não acho{2..57}
(é isso que você quis dizer, certo?) É relevante para o que a intrpc deseja fazer, que é "escolher os arquivos de 2 a 57 em ordem lexicográfica".