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 ...


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 ...

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

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).


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!


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

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 .


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 {} \;

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.


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

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

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 {} \;

0

Ini juga berfungsi:

sudo rm -rf 2018-03-*

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

tetap sederhana


Anda tidak menjelaskan kapan seseorang mungkin ingin mengawali perintah dengan Anda sudojuga tidak memberikan informasi bagaimana cara rmkerjanya dalam konteks jawaban Anda.
Josh Habdas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.