Plages de fichiers à plusieurs chiffres dans l'ordre lexicographique dans zsh

24

Je voudrais spécifier une plage de fichiers (dans l'ordre lexicographique) avec deux entiers (par exemple 2 à 57) en zsh par globbing.

Par exemple: "choisissez les fichiers 2 à 57 dans l'ordre lexicographique sous le chemin qui correspond à un modèle de globalisation".

Je pensais que l'utilisation de crochets le ferait

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

mais apparemment zsh pense que je vous demande les fichiers 2à 5(ou quelque chose comme ça) au lieu des fichiers 2à 57. Des pensées pourquoi? Comment puis-je accomplir cela?

Amelio Vazquez-Reina
la source

Réponses:

30

[2-57]est un jeu de caractères consistant 2, 3, 4, 5et 7, dans zsh et tous les autres caractères génériques et la syntaxe regexp là - bas. Votre modèle de glob *[2-57]correspond à chaque nom de fichier dont le dernier caractère est l'un de ces cinq chiffres.

Je pense que vous vous souvenez mal de la syntaxe du [m,n] qualificatif glob . Les qualificatifs globaux sont toujours placés entre parenthèses à la fin du modèle et le séparateur de plage est une virgule. Le motif *([2,57])s'étend aux 2e, 3e,… et 57e matchs. L'ordre d'extension par défaut est lexicographique (avec une magie spéciale pour trier les nombres dans l'ordre numérique si l' numeric_glob_sortoption est définie); vous pouvez le contrôler avec le qualificatif oor Oglob (par exemple *(om[2,57])pour faire correspondre le 57 fichier le plus récent à l'exception du fichier le plus récent).

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

Pas ce que vous avez demandé, mais lié et peut-être utile aux futurs lecteurs: si vous voulez énumérer les fichiers 2 à 57, qu'ils existent ou non, vous pouvez utiliser une expression d'accolade de plage . Cette fonctionnalité existe également dans bash et ksh.

echo hello{2..57}

Et si vous souhaitez faire correspondre des fichiers dont le nom contient un nombre compris entre 2 et 57, vous pouvez utiliser le modèle <2-57>. Ceci est spécifique à zsh.

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

Notez qu'un modèle comme *<2-57>ne fera probablement pas ce que vous attendez, car il *pourrait également correspondre à des chiffres. Par exemple, file58correspond *<2-57>, avec file5correspondance de la *pièce et 8correspondance de la <2-57>pièce. Le motif *[^0-9]<2-57>évite ce problème.

Gilles 'SO- arrête d'être méchant'
la source
Vous avez raison. Je me souvenais mal du qualificatif global. Merci pour l'explication soignée.
Amelio Vazquez-Reina,
Soit dit en passant, cette déclaration m'a un peu confus: if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. Si les fichiers n'existent pas et qu'il n'y a aucune correspondance, comment l'expansion d'accolade pourrait-elle se développer? (comment se développerait-il différemment du qualificatif mondial?)
Amelio Vazquez-Reina
2
@intrpc se foo{8..11}bardéveloppe en foo8bar foo9bar foo10bar foo11bar. Ce bit d'extension n'est pas lié aux noms de fichiers. De même, foo{eight,nine,ten,eleven}bars'étend à fooeightbar fooninebar footenbar fooelevenbar. Il s'agit d'une extension d'accolade dans ksh / bash / zsh.
Gilles 'SO- arrête d'être méchant'
6

mais zsh pense apparemment que je demande les fichiers 2 à 5 (ou quelque chose comme ça) au lieu des fichiers 2 à 57. Des pensées pourquoi?

Parce que les []crochets indiquent une liste de caractères correspondants (qui peuvent être des chiffres), pas des nombres interprétés mathématiquement. Un tel modèle est mis en correspondance avec un seul caractère. La liste peut contenir des plages, mais des chiffres ou des lettres. [2-57]correspond à "Tous les chiffres compris entre 2 et 5 et 7" .

Pour faire correspondre les nombres de 2 à 57, il serait plus facile d'utiliser une expression de séquence au lieu d'un motif de globalisation (ou avec un tel):

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

Edit : Mais cela, malheureusement, ne vous donnera pas l'ordre lexicographique de tous les fichiers répertoriés - ils seraient regroupés par des terminaisons de numéro communes en raison de l'expansion du shell.

rozcietrzewiacz
la source
Merci @rozcietrzewiacz! J'aurais dû y penser. Mes fichiers contenaient des numéros, alors pendant un moment j'ai pensé []imprimer les choses dans l'ordre ..
Amelio Vazquez-Reina
Votre explication [2-57]est correcte, mais je ne pense pas {2..57}(c'est ce que vous vouliez dire, n'est-ce pas?) Que ce soit pertinent à ce que l'intrpc veut faire, qui est de «choisir les fichiers 2 à 57 dans l'ordre lexicographique».
Gilles 'SO- arrête d'être méchant'
Merci pour le montage (il est temps de dormir, je suppose). Et vous avez raison - j'avais oublié la partie d' ordre lexicographique .
rozcietrzewiacz