abaikan "tidak ada yang cocok"

8

Saya ingin mendaftar semua file dalam folder bernama foldernameyang memiliki ekstensi test, atestatau btest.

Pikiranku adalah berlari ls ./foldername/*.{a,b,}test

Ini berfungsi dengan baik kecuali tidak ada apa-apa dengan ekstensi atest, dalam hal ini saya mendapatkan kesalahan zsh: no matches found: ./foldername/*.atest.

Apakah ada cara saya bisa mengabaikan kesalahan ini dan mencetak file yang ada?

Saya perlu ini bekerja di ZSH dan BASH.

Jonathan Hodgson
sumber
3
Arahkan ulang kesalahan standar ke /dev/null?
DopeGhoti

Jawaban:

9

Mungkin lebih baik melakukan ini dengan find:

find ./foldername -maxdepth 1 -name '*.atest' -o -name '*.btest' -o -name '*.test'
John Moon
sumber
1
mungkin dengan -maxdepth 1, untuk lebih dekat meniru lsperilaku
Jeff Schaller
4
@JeffSchaller, perhatikan bahwa itu -maxdepthadalah ekstensi GNU. Catatan 3 perbedaan lain dengan gumpalan: findakan menyertakan file tersembunyi, tidak mengurutkan daftar dan gagal mencocokkan nama file yang mengandung byte yang tidak membentuk karakter yang valid (seperti $'St\xe9phane.atest'di dalam lokal UTF-8)
Stéphane Chazelas
11

Di

ls -d ./foldername/*.{a,b,}test

{a,b,...} bukan operator glob, itu penjepit ekspansi, yang pertama kali diperluas ke:

ls -d ./foldername/*.atest ./foldername/*.btest ./foldername/*.test

Dan setiap bola berkembang secara individual, dan jika ada bola yang tidak cocok, perintah dibatalkan seperti yang Anda harapkan di zsh(atau fish; di bash, Anda membutuhkan failglobopsi untuk mendapatkan perilaku yang sama).

Di sini, Anda ingin menggunakan satu bola yang cocok dengan semua file itu, dan hanya membatalkan perintah jika bola itu tidak cocok dengan file apa pun:

ls -d ./foldername/*.(a|b|)test

Anda tidak ingin menggunakan nullglob, seolah-olah tidak ada gumpalan yang cocok, itu akan berjalan lstanpa argumen, jadi daftar direktori saat ini. cshnullgloblebih baik dalam hal itu karena menghapus gumpalan yang tidak cocok tetapi masih membatalkan perintah jika semua gumpalan gagal untuk mencocokkan.

Anda tidak akan mau menggunakan nonomatch, karena itu akan memberi Anda perilaku yang rusak bashyang akan memalukan.

Untuk alternatif gumpalan yang bekerja di keduanya zshdan bash, Anda bisa menggunakan gumpalan ksh ( set -o kshglobdalam zshdan shopt -s extglobdalam bash).

Maka, Anda akan melakukan:

ls -d ./foldername/*.@(a|b|)test

atau:

ls -d ./foldername/*.?([ab])test

Tambahkan failglobopsi bashuntuk menghindari gumpalan diteruskan secara harfiah ke lssaat tidak cocok.

Lihat Mengapa nullglob tidak default? untuk informasi lebih lanjut.

Stéphane Chazelas
sumber
Saya tidak yakin mengapa ini merupakan persyaratan OP, tetapi apakah ada extglob yang berfungsi untuk ini baik di bash dan zsh? Saya harus menggunakan ?(...)atau +(...)untuk bash.
Jeff Schaller
@JeffSchaller, lihat edit
Stéphane Chazelas