Saya perlu menghapus semua file dengan ekstensi .gif kecuali satu file dengan nama say "filename.gif". Apa cara optimal untuk melakukan ini di terminal?
Perintah rm *.gif
menghapus semua file gif termasuk file filename.gif
.
sumber
Saya perlu menghapus semua file dengan ekstensi .gif kecuali satu file dengan nama say "filename.gif". Apa cara optimal untuk melakukan ini di terminal?
Perintah rm *.gif
menghapus semua file gif termasuk file filename.gif
.
Inilah solusi sederhana yang mungkin sebaiknya Anda gunakan:
mv filename.gif filename.gif.keep
rm *.gif
mv filename.gif.keep filename.gif
Tidak ada yang istimewa dengan .keep
ekstensi, ini hanya membuatnya agar nama file sementara tidak berakhir .gif
.
Jika Anda tidak boleh mengganti nama file (dan ada situasi skrip di mana ini penting):
for X in *.gif; do
if [ "$X" != "filename.gif" ]; then
rm "$X"
fi
done
Atau Anda dapat menulisnya lebih pendek seperti ini:
for X in *.gif; do [ "$X" != "filename.gif" ] && rm "$X"; done
Anda mungkin lebih suka menggunakan find
; itu sangat kuat, Anda mungkin menganggapnya lebih mudah dibaca, dan lebih baik menangani nama file aneh dengan karakter seperti *
di dalamnya .
find . -maxdepth 1 -not -name 'filename.gif' -name '*.gif' -delete
Saya telah menggunakan -not
operator untuk keterbacaan, tetapi jika kepatuhan POSIX penting - jika Anda tidak menggunakan GNU find, atau jika ini untuk skrip Anda bermaksud mendistribusikan ulang ke orang lain atau berjalan di berbagai sistem - Anda harus gunakan !
operator sebagai gantinya:
find . -maxdepth 1 ! -name 'filename.gif' -name '*.gif' -delete
Satu hal praktis tentang hal find
ini adalah Anda dapat dengan mudah memodifikasi perintah untuk case-insensitivity, sehingga ia menemukan dan menghapus file dengan ekstensi seperti .GIF
juga:
find . -maxdepth 1 -not -name 'filename.gif' -iname '*.gif' -delete
Harap dicatat bahwa saya telah digunakan -iname
di tempat -name
untuk pola pencarian *.gif
tapi saya tidak menggunakannya untuk filename.gif
. Agaknya Anda tahu persis apa nama file Anda, dan -iname
akan cocok dengan huruf kapital alternatif tidak hanya dalam ekstensi , tetapi di mana saja dalam nama file.
Semua solusi ini hanya menghapus file yang berada langsung di direktori saat ini . Mereka tidak menghapus file yang tidak ada dalam direktori saat ini, dan mereka tidak menghapus file yang berada di subdirektori dari direktori saat ini.
Jika Anda ingin menghapus file di mana saja yang terdapat dalam direktori saat ini (yaitu, termasuk dalam subdirektori, dan dalam subdirektori dari subdirektori tersebut, dan sebagainya - file yang terkandung dalam direktori saat ini atau salah satu turunannya), gunakan find
tanpa maxdepth -1
:
find . -not -name 'filename.gif' -name '*.gif' -delete
Hati-hati dengan ini!
Anda juga dapat mengatur nilai lain dengan -maxdepth
. Misalnya, untuk menghapus file di direktori saat ini dan anak-cucunya tetapi tidak lebih dalam:
find . -maxdepth 3 -not -name 'filename.gif' -name '*.gif' -delete
Pastikan Anda tidak pernah memprioritaskan -delete
, sebelum ekspresi lainnya! Anda akan melihat saya selalu menempatkan -delete
di akhir. Jika Anda meletakkannya di awal, itu akan dievaluasi terlebih dahulu, dan semua file di bawah .
(termasuk file yang tidak berakhir .gif
dan file dalam sub-sub-sub ... direktori dari .
) akan dihapus!
Untuk informasi lebih lanjut , lihat halaman manual untuk bash
dan sh
dan untuk perintah yang digunakan dalam contoh ini: mv
, rm
, [
, dan (terutama) find
.
find
, yang sangat fleksibel.find
yang memang merupakan temuan yang bagus.find
menangani nama file aneh dengan*
mereka lebih baik daripada for-loop? Untuk loop menangani file dengan*
baik, karena Anda telah menggunakan tanda kutip ganda.Jika Anda menggunakan
bash
(shell default),extglob
opsi shell memungkinkan Anda untuk menggunakan sintaks yang cocok dengan pola yang diperluas. Untuk mengaktifkannya, gunakanshopt
perintah builtin:(Saya menyertakan baris itu di
.bashrc
file saya .)Antara lain, itu memberikan akses ke
!()
operator, yang cocok dengan pola apa pun yang tidak di dalam parens. Untuk tujuan Anda:Informasi lebih lanjut tersedia di
man bash
bawah "Pencocokan Pola".sumber
extglob
harus diaktifkan, tetapi tidak ada hal buruk terjadi jika dinonaktifkan (dalam hal ini, ini tidak berfungsi). Dan tampaknya diaktifkan secara default, meskipun saya tidak memilikishopt -s extglob
file konfigurasi (atau global) saya. Jika ada penjelasan sederhana mengapa itu berhasil bagi saya di luar kotak, Anda mungkin ingin menambahkannya ke jawaban ini; atau saya dapat memposting pertanyaan baru.Buka Terminal dengan Ctrl+ Alt+ Tdan ketik:
Perbedaan antara
-delete
dan-exec rm -vf {} \;
adalah bahwa dengan opsi kedua, Anda akan dapat melihat file mana yang telah dihapus, karena-v
benderanya. Itu sesuatu yang tidak bisa dilakukan dengan-delete
opsi. (-name -delete
akan mencetak nama file, tetapirm
dengan-v
mengungkapkan jika setiap file berhasil dihapus.)sumber
Ada
GLOBIGNORE
variabelnya. Dariman bash
:Jadi, cara sederhana adalah dengan hanya mengatur
GLOBGINORE
nama file yang dimaksud:Jadi, dalam kasus Anda:
Tentu saja, karena
GLOBIGNORE
berisi pola, Anda dapat menggunakannya kapan pun Anda ingin mengecualikan pola:Keuntungan (?!) Dari
GLOBIGNORE
pengaturan itu secara otomatis mengecualikan.
dan..
tidak cocok, dan memungkinkandotglob
:Jadi, cara sederhana menghapus semua file dan folder dalam direktori:
The
*
akan cocok nama file yang dimulai dengan.
, sejakGLOBIGNORE
diaktifkandotglob
, tetapi tidak akan cocok.
atau..
, sehingga Anda tidak akan mempengaruhi direktori induk seperti itu.sumber