Bagaimana cara menghapus banyak file dengan awalan dan akhiran yang umum?

21

Saya memiliki banyak file bernama

sequence_1_0001.jpg  
sequence_1_0002.jpg  
sequence_1_0003.jpg  
...

dan file bernama

sequence_1_0001.hmf  
sequence_1_0002.hmf  
sequence_1_0003.hmf  
...

dan file bernama

sequence_2_0001.jpg  
sequence_2_0002.jpg  
sequence_2_0003.jpg  
...

dan

sequence_2_0001.hmf  
sequence_2_0002.hmf  
sequence_2_0003.hmf  
...

Saya hanya ingin menghapus file yang dimulai dengan 'sequence_1' dan diakhiri dengan '.hmf', tetapi saya tidak ingin menghapusnya satu per satu, karena ada ribuan file. Bagaimana saya bisa menentukan perintah rm yang ingin saya hapus semua yang dimulai dengan prefilx 'sequence_1' dan diakhiri dengan '.hmf'?

Saat ini saya sedang bekerja dengan sistem RedHat Linux, tetapi saya ingin tahu bagaimana melakukannya pada distribusi lain juga.

Paul
sumber

Jawaban:

28
rm sequence_1*.hmf

menghapus file yang diawali dengan sequence_1dan diakhiri dengan .hmf.


Globbing adalah proses di mana shell Anda mengambil pola dan memperluasnya ke daftar nama file yang cocok dengan pola itu. Jangan bingung dengan ekspresi reguler, yang berbeda. Jika Anda menghabiskan sebagian besar waktu Anda di bash, Wiki Wooledge memiliki halaman yang bagus tentang globbing (ekspansi pathname) . Jika Anda ingin portabilitas maksimum, Anda juga ingin membaca spesifikasi POSIX pada pencocokan pola /.


Jika Anda mengalami kesalahan "Daftar argumen terlalu panjang" , Anda dapat melihat BashFAQ 95 , yang membahas hal ini. Solusi paling sederhana adalah memecah pola gumpalan menjadi beberapa bongkahan yang lebih kecil, hingga kesalahan hilang. Dalam kasus Anda, Anda mungkin bisa lolos dari pemisahan pertandingan dengan angka awalan 0 hingga 9, sebagai berikut:

for c in {0..9}; do rm sequence_1_"$c"*.hmf; done
rm sequence_1*.hmf  # catch-all case
jw013
sumber
Ini adalah pekerjaan yang sangat cerdas di sekitar kesalahan 'daftar argumen terlalu panjang'. Dalam kasus saya, saya memiliki dua puluh ribu file, jadi saya kira saya harus menggunakan for for loop dari 0, .., 20. Kanan?
Paul
@ Paul Benar, pecahkan daftar menjadi sebanyak mungkin potongan yang Anda butuhkan, meskipun pada beberapa titik findpendekatannya menjadi lebih mudah daripada menebak dan memeriksa.
jw013
14

Meskipun jawaban jw013 adalah benar wrt globbing, perintah itu mungkin gagal jika Anda memiliki ribuan kecocokan: baris perintah diperluas yang rm sequence_1_0001.hmf sequence_1_0002.hmf ...dihasilkan oleh shell mungkin terlalu besar.

Seperti yang disarankan Dom, Anda juga dapat menggunakan -deleteopsi dengan find:

find . -maxdepth 1 -type f -name 'sequence_1*.hmf' -delete

Baik -maxdepthdan -delete, sementara tidak dalam standar POSIX cukup umum dalam findimplementasi di alam liar. Distribusi Linux umumnya menggunakan GNU find, yang tentunya mendukung opsi-opsi itu.

Tak berguna
sumber
2
Jika Anda bisa, gunakan opsi -delete untuk menemukan, itu tidak bercabang untuk setiap file ...
Dom
Tambah, sorakan. Sepertinya -deleteharus didukung pada sistem GNU dan BSD baru-baru ini, sedangkan -print0hanya GNU. Jadi sepertinya lebih portabel juga (meskipun seharusnya tidak membuat perbedaan untuk OP).
berguna
Setidaknya temuan OS X memiliki -print0, tetapi tidak termasuk dalam POSIX.
Lri
5
rm sequence_1_{0000..0999}.hmf
rm sequence_1_{1000..1999}.hmf
rm sequence_1_{2000..2999}.hmf
...

akan bekerja juga di Bash.

Pengguna tidak diketahui
sumber
Perluasan brace membutuhkan bash, dan bentuk nol empuk perlu versi 4, saya percaya.
jw013