Rentang multidigit file dalam urutan leksikografis dalam zsh

24

Saya ingin menentukan serangkaian file (dalam urutan leksikografis) dengan dua bilangan bulat (misalnya 2 hingga 57) dalam zsh oleh globbing.

Misalnya: "pilih file 2 hingga 57 dalam urutan leksikografis di bawah jalur yang cocok dengan beberapa pola globbing".

Saya pikir menggunakan tanda kurung akan melakukannya

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

tapi zsh rupanya berpikir saya meminta file 2untuk 5(atau sesuatu seperti itu) alih-alih file 2ke 57. Adakah pemikiran mengapa? Bagaimana saya bisa mencapai ini?

Amelio Vazquez-Reina
sumber

Jawaban:

30

[2-57]adalah set karakter yang terdiri dari 2, 3, 4, 5dan 7, di zsh dan setiap wildcard lain dan sintaks regexp di luar sana. Pola glob Anda *[2-57]cocok dengan setiap nama file yang karakter terakhirnya adalah salah satu dari lima digit itu.

Saya pikir Anda salah mengingat sintaksis [m,n] kualifikasi glob . Kualifikasi global selalu menggunakan tanda kurung di akhir pola, dan pemisah rentang adalah koma. Pola *([2,57])meluas ke pertandingan ke-2, ke-3, ..., ke-57. Urutan ekspansi standar adalah leksikografis (dengan beberapa sihir khusus untuk mengurutkan angka dalam urutan numerik jika numeric_glob_sortopsi disetel); Anda dapat mengontrolnya dengan oatau Oglob qualifier (misalnya *(om[2,57])untuk mencocokkan 57 file terbaru kecuali satu file terbaru).

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

Bukan yang Anda minta, tetapi terkait dan mungkin bermanfaat bagi pembaca di masa mendatang: jika Anda ingin menghitung file 2 hingga 57 apakah ada atau tidak, Anda dapat menggunakan ekspresi kurung kurawal . Fitur ini juga ada di bash dan ksh.

echo hello{2..57}

Dan jika Anda ingin mencocokkan file yang namanya berisi angka antara 2 dan 57, Anda dapat menggunakan polanya <2-57>. Ini khusus untuk zsh.

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

Perhatikan bahwa pola suka *<2-57>cenderung tidak melakukan apa yang Anda harapkan, karena angka tersebut *dapat cocok dengan angka juga. Misalnya, file58cocok *<2-57>, dengan file5mencocokkan *bagian dan 8mencocokkan <2-57>bagian. Pola *[^0-9]<2-57>menghindari masalah ini.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Kamu benar. Saya salah mengingat kualifikasi glob. Terima kasih atas penjelasannya.
Amelio Vazquez-Reina
By the way, pernyataan ini membuat saya sedikit bingung: if you want to enumerate files 2 to 57 whether they exist or not, you can use a range brace expression. Jika file tidak ada dan tidak ada yang cocok, bagaimana ekspansi brace akan tahu bagaimana cara memperluas? (bagaimana ini berkembang secara berbeda dari kualifikasi glob?)
Amelio Vazquez-Reina
2
@ intrpc foo{8..11}barmeluas ke foo8bar foo9bar foo10bar foo11bar. Sedikit ekspansi ini tidak terkait dengan nama file. Demikian pula, foo{eight,nine,ten,eleven}barmemperluas ke fooeightbar fooninebar footenbar fooelevenbar. Ini adalah ekspansi brace di ksh / bash / zsh.
Gilles 'SO- stop being evil'
6

tapi zsh rupanya berpikir saya meminta file 2 sampai 5 (atau sesuatu seperti itu) daripada file 2 hingga 57. Ada yang berpikir mengapa?

Karena []tanda kurung menunjukkan daftar karakter yang cocok (yang dapat berupa angka), bukan angka yang ditafsirkan secara matematis. Pola tersebut dicocokkan dengan satu karakter. Daftar dapat berisi rentang, tetapi dari angka atau huruf. [2-57]pertandingan diperluas ke "Semua digit dalam rentang dari 2 hingga 5 dan 7" .

Untuk mencocokkan angka dari 2 hingga 57, akan lebih mudah untuk menggunakan ekspresi urutan daripada pola globbing (atau bersama-sama dengan itu):

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

Sunting : Tapi ini, sayangnya, tidak akan memberi Anda urutan leksikografis semua file yang terdaftar - mereka akan dikelompokkan berdasarkan nomor akhir yang umum karena ekspansi shell.

rozcietrzewiacz
sumber
Terima kasih @rozcietrzewiacz! Aku seharusnya memikirkan itu. File-file saya memiliki angka di dalamnya, jadi untuk sesaat saya pikir []sedang mencetak barang-barang secara berurutan ..
Amelio Vazquez-Reina
Penjelasan Anda tentang hal [2-57]itu benar, tetapi saya tidak berpikir {2..57}(itu yang Anda maksudkan, bukan?) Relevan dengan apa yang ingin dilakukan intrpc, yaitu "memilih file 2 hingga 57 dalam urutan leksikografis".
Gilles 'SO- stop being evil'
Terima kasih atas hasil editnya (waktunya tidur, kurasa). Dan Anda benar - saya lupa tentang bagian urutan leksikografis .
rozcietrzewiacz