Intervalli multidigit di file in ordine lessicografico in zsh


24

Vorrei specificare un intervallo di file (in ordine lessicografico) con due numeri interi (ad es. Da 2 a 57) in zsh da globbing.

Ad esempio: "seleziona i file da 2 a 57 in ordine lessicografico sotto il percorso che corrisponde a un modello di globbing".

Ho pensato che usare le parentesi quadre avrebbe funzionato

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

ma a quanto pare pensa zsh sto chiedendo i file 2a 5(o qualcosa di simile) invece di file 2a 57. Qualche idea sul perché? Come posso farlo?

Risposte:


30

[2-57]è un insieme di caratteri composto da 2, 3, 4, 5e 7, in zsh e ogni altro jolly e sintassi regexp fuori. Il tuo modello glob *[2-57]corrisponde a tutti i nomi di file il cui ultimo carattere è una di quelle cinque cifre.

Penso che tu stia ricordando male la sintassi del [m,n] qualificatore glob . I qualificatori Glob vanno sempre tra parentesi alla fine del pattern e il separatore di intervallo è una virgola. Il modello si *([2,57])espande al 2 °, 3 °, ... 57 ° incontro. L'ordine di espansione predefinito è lessicografico (con qualche magia speciale per ordinare i numeri in ordine numerico se l' numeric_glob_sortopzione è impostata); puoi controllarlo con il qualificatore oo Oglob (ad es. *(om[2,57])per abbinare il 57 file più recente tranne quello più recente).

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

Non quello che hai chiesto, ma correlato e forse utile ai lettori futuri: se vuoi enumerare i file da 2 a 57, che esistano o meno, puoi usare un'espressione di parentesi graffa . Questa funzione esiste anche in bash e ksh.

echo hello{2..57}

E se si desidera abbinare i file il cui nome contiene un numero compreso tra 2 e 57, è possibile utilizzare il modello <2-57>. Questo è specifico di zsh.

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

Si noti che *<2-57>è probabile che un modello come non faccia quello che ci si aspetta, perché *potrebbe corrispondere anche alle cifre. Ad esempio, le file58corrispondenze *<2-57>, con la file5corrispondenza della *parte e la 8corrispondenza della <2-57>parte. Il modello *[^0-9]<2-57>evita questo problema.


Hai ragione. Stavo fraintendendo la qualifica glob. Grazie per l'attenta spiegazione.
Amelio Vazquez-Reina,

A proposito, questa affermazione mi ha confuso un po ': if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. Se i file non esistono e non ci sono corrispondenze, come farebbe l'espansione del controvento? (come si espanderebbe in modo diverso dalle qualificazioni glob?)
Amelio Vazquez-Reina

2
@intrpc si foo{8..11}barespande in foo8bar foo9bar foo10bar foo11bar. Questo bit di espansione non è correlato ai nomi dei file. Allo stesso modo, si foo{eight,nine,ten,eleven}barespande a fooeightbar fooninebar footenbar fooelevenbar. Questa è l' espansione di parentesi graffe in ksh / bash / zsh.
Gilles 'SO- smetti di essere malvagio' il

6

ma apparentemente zsh pensa che sto chiedendo i file da 2 a 5 (o qualcosa del genere) invece dei file da 2 a 57. Qualche idea sul perché?

Poiché le []parentesi indicano un elenco di caratteri corrispondenti (che possono essere cifre), non numeri interpretati matematicamente. Tale modello è abbinato a un singolo personaggio. L'elenco può contenere intervalli, ma di cifre o lettere. [2-57]match si espande in "Tutte le cifre nell'intervallo da 2 a 5 e un 7" .

Per abbinare i numeri da 2 a 57, sarebbe più semplice usare un'espressione di sequenza invece di un modello di globbing (o insieme a tale):

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

Modifica : Ma questo, sfortunatamente, non ti darà l'ordine lessicografico di tutti i file elencati: sarebbero raggruppati per terminazioni numeriche comuni a causa dell'espansione della shell.


Grazie @rozcietrzewiacz! Avrei dovuto pensarci. I miei file contenevano numeri, quindi per un momento ho pensato di []stampare le cose in ordine ...
Amelio Vazquez-Reina,

La tua spiegazione [2-57]è corretta, ma non credo {2..57}(questo è ciò che intendevi, giusto?) È rilevante per ciò che Intrpc vuole fare, che è "selezionare i file da 2 a 57 in ordine lessicografico".
Gilles 'SO- smetti di essere malvagio' il

Grazie per la modifica (è ora di andare a dormire, immagino). E hai ragione: mi ero dimenticato della parte dell'ordine lessicografico .
rozcietrzewiacz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.