Bagaimana saya bisa menghapus semua file dari ekstensi tertentu di direktori saat ini secara rekursif?

531

Bagaimana cara menghapus semua file dengan aman dengan ekstensi tertentu (mis. .bak) Dari direktori saat ini dan semua subfolder menggunakan satu baris perintah? Sederhananya, saya takut menggunakannya rmkarena saya salah menggunakannya sekali dan sekarang saya butuh saran.

pengguna216038
sumber

Jawaban:

840

Anda bahkan tidak perlu menggunakan rmdalam kasus ini jika Anda takut. Gunakan find:

find . -name "*.bak" -type f -delete

Tetapi gunakan dengan hati-hati. Jalankan dulu:

find . -name "*.bak" -type f

untuk melihat file mana yang akan Anda hapus.

Juga, pastikan itu -deleteadalah argumen terakhir dalam perintah Anda. Jika Anda meletakkannya sebelum -name *.bak argument, itu akan menghapus semuanya .

Lihat man finddan man rmuntuk info lebih lanjut dan lihat juga pertanyaan terkait ini di SE:

Radu Rădeanu
sumber
Bagaimana ini berbeda rm *.bak?
sayantankhan
10
@ Bolt64 Anda rm *.baktidak akan berfungsi untuk subdirektori.
Radu Rădeanu
Dengan pengaturan default rm *.bakhanya akan menghapus semua file yang diakhiri dengan .bak di direktori saat ini. UNTUK juga melakukan hal-hal dalam subdirektori yang Anda perlukan untuk bermain-main dengan gumpalan, gunakan opsi -r atau gunakan contoh temukan.
Hennes
9
@ Henry Hati-hati dengan rm -r *.bak! Itu juga menghapus direktori yang diakhiri .bakdengan semua konten mereka.
Radu Rădeanu
37
Pastikan itu -deleteadalah argumen terakhir dalam perintah Anda. Jika Anda meletakkannya sebelum -name *.bakargumen, itu akan menghapus semuanya.
Michael
40
find . -name "*.bak" -type f -print0 | xargs -0 /bin/rm -f
lokers
sumber
1
Selamat datang di askubuntu! Meskipun ini adalah jawaban yang benar-benar valid saya tidak berpikir ada keuntungan dalam menggunakan ini daripada -deletebendera find. Informasi lebih lanjut dapat ditemukan di entri manual GNU untuk menghapus file dengan find .
Glutanimate
2
Anda mungkin benar, itu hanya solusi alternatif, mungkin lebih mentah;)
lokers
11
Ini bukan hanya alternatif tetapi contoh bagaimana perintah lain dapat dikombinasikan bersama dengan pipa '|'. +1
Boris Pavlovic
13
Solusi alternatif ini bekerja pada lingkungan lain yang kurang -delete (seperti cygwin)
ciriarte
2
Saya pikir ini adalah jawaban terbaik di sini.
Léo Léopold Hertz 준영
33

Pertama jalankan perintah shopt -s globstar. Anda dapat menjalankannya di baris perintah, dan itu hanya akan berpengaruh di jendela shell itu. Anda dapat memasukkannya ke dalam .bashrc, dan kemudian semua kerang yang baru mulai akan mengambilnya. Efek dari perintah itu adalah membuat **/file yang cocok di direktori saat ini dan subdirektori secara rekursif (secara default, **/berarti hal yang sama dengan */: hanya di subdirektori langsung). Kemudian:

rm **/*.bak

(atau gvfs-trash **/*.bakapa pun yang Anda miliki).

Gilles
sumber
21

Menghapus file bagi saya bukanlah sesuatu yang harus Anda gunakan rmuntuk. Berikut ini sebuah alternatif:

sudo apt-get install gvfs     # install a tool that allows you to put stuff in the trash
alias "trash"="gvfs-trash"    # you can also put this in .bash_aliases or simply use the command without alias
trash *.bak                   # trash the files (thus moving them to the trash bin)

Seperti yang dinyatakan Flimm dalam komentar:

Paket trash-climelakukan hal yang sama gvfs-trashtanpa ketergantungan pada gvfs.

Begitu:

sudo apt-get install trash-cli

Anda tidak perlu membuat alias untuk ini, karena trash-clipaket menyediakan perintah trash, yang melakukan apa yang kita inginkan.

Seperti yang Eliah Kagan jelaskan dalam komentar yang luas, Anda juga dapat membuat ini menggunakan rekursif find. Dalam hal ini Anda tidak dapat menggunakan alias, jadi perintah di bawah ini menganggap Anda telah menginstal trash-cli. Saya meringkas komentar Eliah:

Perintah ini menemukan dan menampilkan semua .bakfile dan symlink di mana saja di direktori saat ini atau subdirektori atau di bawahnya.

find . -name '*.bak' -xtype f

Untuk menghapusnya, tambahkan sebuah -execdengan trashperintah:

find . -name '*.bak' -xtype f -exec trash {} +

-xtype fmemilih file dan symlink ke file, tetapi bukan folder. Untuk menghapus folder .bak juga, hapus bagian itu, dan gunakan -execdir, yang menghindari cannot trash non-existentkesalahan untuk .bakfile di dalam .bakdirektori:

find . -name '*.bak' -execdir trash {} +
jangan
sumber
4
"Jangan gunakan rmuntuk menghapus sesuatu" adalah pernyataan yang kontroversial tetapi saya harus setuju bahwa sering kali lebih bijaksana untuk menggunakan sesuatu yang akan membuat Anda membatalkan sesuatu.
Oli
2
Paket trash-climelakukan hal yang sama gvfs-trashtanpa bergantung pada gvfs.
Flimm
Saya telah mengeditnya di jawaban, lain kali silakan mengedit sendiri.
don.joey
@ don.joey Jawaban ini sepertinya mengatakan find . -name "*.bak" -type fmenampilkan apa yang trash *.bakdihapus. Benarkah itu yang Anda maksud? Anda dapat memindahkan direktori ke tempat sampah dengan trashatau gvfs-trash, tetapi trash *.bakhanya akan memindahkan file dan direktori yang namanya berakhir dengan .bakdan yang berada langsung di direktori saat ini. Shell mengembang *.bak, jadi trash *.baktidak akan memengaruhi .bakfile dalam subdirektori yang tidak dinamai .bak.
Eliah Kagan
1
@ don.joey Ya ls *.bak(yang saya pikir maksud Anda) mencantumkan trash *.baksampah apa . find . -name '*.bak' -xtype f -exec trash {} +trash semua .bakfile di mana saja di bawah .. Itu tidak bisa menggunakan alias, jadi instal trash-cliatau tulis gvfs-trashsaja. Ini sebuah contoh. -xtype fmemilih file dan symlink ke file, tetapi bukan folder. Untuk menghapus .bak folder juga, gunakan find . -name '*.bak' -execdir trash {} +, yang menghindari cannot trash non existentkesalahan untuk .bakfile di dalam .bakdirektori. Silakan menggunakan semua ini dalam jawaban Anda.
Eliah Kagan
5

Jika Anda ingin menghapus semua file dari jenis tertentu, tetapi hanya 1 folder "dalam" dari folder saat ini:

find . -maxdepth 2 -name "*.log" -type f -delete

-maxdepth 2 karena direktori saat ini " . " dianggap sebagai folder pertama.

Orang munafik
sumber
1

Jawaban cepat:

  • Hapus semua file dengan nama yang dianggap atau postfix secara rekursif:

    find . -name '*.pyc' -type f -delete

  • Hapus semua direktori dengan nama yang dipertimbangkan secara rekursif:

    find ~ -path '*/__pycache__/*' -delete‍‍‍
    find ~ -type d -name '__pycache__' -empty -delete‍‍‍
    

    Agak kurang terkontrol, tetapi dalam satu baris:

    find ~ -path '*/__pycache__*' -delete
    

[ CATATAN ]:

dadalah opsi direktori dan fmerupakan opsi file.

Benyamin Jafari
sumber
0

Jika Anda berada di dalam git repo, Anda dapat menggunakan:

git clean -fdx

Ini menghapus file dan file yang tidak terlacak dalam .gitignore.

Vasantha Ganesh K
sumber