Menghapus file secara rekursif

140

Adakah yang punya solusi untuk menghapus file sial ._ dan .DS_Store yang didapat setelah memindahkan file dari Mac ke Server Linux?

tentukan direktori mulai dan lepaskan? seperti / var / www / html / bawah ...

JT.
sumber
Meskipun ini bukan duplikat IMO, Anda harus melihat ini: stackoverflow.com/questions/1280429/…
Grundlefleck
Meski bukan itu yang Anda tanyakan. Saya berpendapat ini adalah solusi yang lebih baik: unix.stackexchange.com/questions/9665/…
Viktor

Jawaban:

169

ubah ke direktori, dan gunakan:

find . -name ".DS_Store" -print0 | xargs -0 rm -rf
find . -name "._*" -print0 | xargs -0 rm -rf

Tidak diuji, coba dulu tanpa xargs!

Anda dapat mengganti periode setelah menemukan, dengan direktori, alih-alih mengubah ke direktori terlebih dahulu.

find /dir/here ...
X-Istence
sumber
2
Saya tahu pertanyaannya tidak menanyakannya, tetapi saya tidak pernah dapat mengingat: apakah contoh Anda menangani nama file dengan spasi?
Grundlefleck
4
Ya, untuk itulah print0 dan -0 untuk xargs. Biasanya itu tidak akan menangani spasi dengan benar, namun dengan print0 itu akan mencetak nama file dengan karakter nol di akhir baris, yang xarg dengan -0 kemudian akan digunakan untuk melewati path penuh ke xargs tanpa kesempatan memiliki spasi sedang digunakan parameter kedua atau ketiga untuk perintah rm yang bisa sangat buruk!
X-Istence
7
@X: findutils yang lebih baru mendukung -deletetindakan, yang dapat mempersingkat ini. @JT: Pencarian ini secara rekursif di bawah .. Bergantung pada berapa banyak file dan subdirektori ... tidak bisakah Anda hanya melarang file-file itu diunggah?
ephemient
1
Menggunakan -rflag (rekursif) tidak disarankan dalam kasus ini karena Anda tidak ingin menghapus direktori apa pun ..
Daniel Zohar
2
@IlmariKaronen: poin bagus. Bukankah command rmsolusi yang lebih baik (yaitu, lebih langsung)? (Secara "langsung" yang saya maksudkan adalah secara khusus menangani masalah yang dihadapi dan tidak ada yang lain, dan karena itu lebih kecil kemungkinannya memiliki efek samping yang tidak diinginkan, dan juga akan menjadi lebih jelas bagi siapa saja yang harus menjaga kode tersebut. nanti.)
iconoclast
93
find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete
OneOfOne
sumber
86

Findutils baru mendukung -delete, jadi:

find . -name ".DS_Store" -delete

Menambahkan -print juga untuk mendapatkan daftar penghapusan.

Perintah akan bekerja untuk Anda jika Anda memiliki sistem POSIX terbaru, saya percaya. Setidaknya itu berfungsi untuk saya pada OS X 10.8 dan bekerja untuk orang lain yang telah mengujinya di macOS 10.12 (Mojave).

Berikan kredit pada @femient dalam komentar di kiriman @ X-Istence (merasa cukup membantu untuk mendapatkan jawabannya sendiri).

rattray
sumber
1
Bekerja kembali di OSX 10.6 juga.
Hoss
3
Solusi terbersih dan paling sederhana, +1!
limist
6
@OneOfOne: seperti komentar saya, saya mendapat ini dari @ ephemient. Sebagai pemula untuk bash, saya menemukan solusi Anda (mungkin lebih benar) jauh lebih mudah dibaca dan tidak dapat digunakan. Mereka mungkin identik secara fungsional tetapi saya menemukan sintaks ini memberikan lebih banyak kejelasan.
rattray
1
'.' tidak perlu karena findberulang ke direktori kerja saat ini secara default.
Tom Russell
Dalam versi yang lebih baru dari program, direktori dapat dihilangkan, dan itu akan menyiratkan direktori kerja saat ini ( wikipedia ). Anda masih membutuhkan .di macOS 10.12 (Sierra).
Dem Pilafian
18

Perintah sederhana:

rm `find ./ -name '.DS_Store'` -rf
rm `find ./ -name '._'` -rf

Semoga berhasil!

KimKha
sumber
1
Ini sangat bagus. TAPI kata hati-hati, saya baru saja menggunakan ini rm -i ./ -nama '* py'` -rf , which did NOT prompt me to delete files. you will need to take it on the end (i.e. -rfi`). Terima kasih Tuhan untuk skrip cadangan saya.
ryanjdillon
1
Jika ada terlalu banyak file, ini bisa dipecahkan dengan kesalahan:-bash: /bin/rm: Argument list too long
Viktor
12
cd /var/www/html && find . -name '.DS_Store' -print0 | xargs -0 rm
cd /var/www/html && find . -name '._*' -print0 | xargs -0 rm
mopoke
sumber
2
Saya lebih menyukai yang ini hanya karena "rm" tidak memiliki "-r" yang tidak diperlukan untuk tugas khusus ini.
lotsoffreetime
6

Anda dapat beralih ke zsh bukannya bash. Ini memungkinkan Anda menggunakan ** untuk mencocokkan file di mana saja di pohon direktori:

$ rm /var/www/html/**/_* /var/www/html/**/.DS_Store

Anda juga dapat menggabungkannya seperti ini:

$ rm /var/www/html/**/(_*|.DS_Store)

Zsh memiliki banyak fitur lain yang kurang dimiliki oleh bash, tetapi satu saja yang layak dilakukan. Ini tersedia di sebagian besar (mungkin semua) distro linux, serta cygwin dan OS X.

Anda dapat menemukan informasi lebih lanjut di situs zsh .

Dave Kirby
sumber
1
Kemungkinan masalah: karena Anda tidak menggunakan xargs, Anda mungkin mengalami pembatasan panjang argumen baris perintah. Juga, Bash 4 mendukung **juga :-) (meskipun tidak secara default, shopt -s globstarperlu diatur)
ephemient
4
find . -name "FILE-TO-FIND"-exec rm -rf {} \;
Martin Beckett
sumber
Menggunakan exec untuk setiap file yang ditemukan tidak cepat. Lebih cepat menemukan mencetaknya dan kemudian menggunakan xargs untuk memanggil rm sekali.
X-Istence
3
Namun, jika Anda memiliki findyang mendukungnya, +seperti-xargs: find . -name "FILE-TO-FIND" -exec rm -rf {} +- (juga, Anda kehilangan spasi sebelumnya -exec)
Dijeda hingga pemberitahuan lebih lanjut.
3
kami tidak pernah memiliki xargs di hari saya. Dan kami harus berjalan ke sekolah, menanjak ke dua arah .......
Martin Beckett
3

Contoh untuk menghapus "Thumbs.db" secara rekursif;

find . -iname "Thumbs.db" -print0 | xargs -0 rm -rf

Validasi berdasarkan:

find . -iname "Thumbs.db"

Ini seharusnya sekarang, tidak menampilkan salah satu entri dengan "Thumbs.db", di dalam jalur saat ini.

parasrish
sumber
Pastikan jawaban Anda mencetak daftar apa yang dihapus dan jelaskan mengapa seseorang mungkin ingin menggunakan xargsdan print0bukannya exec(ada alasan).
Josh Habdas
3

Lebih baik melihat apa yang dihapus dengan menambahkan -cetak pada jawaban ini

find /var/www/html \( -name '.DS_Store' -or -name '._*' \) -delete -print
Ahmad Yoosofan
sumber
2

jika Anda memiliki Bash 4.0 ++

#!/bin/bash
shopt -s globstar
for file in /var/www/html/**/.DS_Store /var/www/html/**/._ 
do
 echo rm "$file"
done
ghostdog74
sumber
2
Menjalankan salinan rm baru untuk setiap file boros.
X-Istence
2
@ X-Istence optimasi prematur boros
Lucina
Terpilih untuk orisinalitas dan penggunaan inovasi bash yang lebih baru.
Josh Habdas
1

Beberapa hal yang perlu diperhatikan:

'-delete' tidak rekursif. Jadi jika .T TemporaryItems (folder) memiliki file di dalamnya, perintah gagal.

Ada banyak file sial yang dibuat oleh mac: .DS_Store ._. DS_Store .T TemporaryItems .apdisk

Perintah yang satu ini membahas semuanya. Menghemat dari menjalankan pencarian berulang-ulang untuk beberapa pertandingan.

find /home/foo \( -name '.DS_Store' -or -name '._.DS_Store' -or -name '._*' -or -name '.TemporaryItems' -or -name '.apdisk' \) -exec rm -rf {} \;
Karan Bhalla
sumber
0

Ini juga berfungsi:

sudo rm -rf 2018-03-*

di sini file menghapus Anda dengan nama format 2018-03- (sesuatu yang lain)

tetap sederhana

pranavhd
sumber
Anda tidak menjelaskan kapan seseorang mungkin ingin mengawali perintah dengan Anda sudojuga tidak memberikan informasi bagaimana cara rmkerjanya dalam konteks jawaban Anda.
Josh Habdas