rm -rf semua file dan semua file tersembunyi tanpa. & .. kesalahan

83

rm -rf /some/path/* menghapus semua file yang tidak disembunyikan di dir itu (dan subdir).

rm -rf /some/path/.* menghapus semua file tersembunyi di dir itu (tetapi tidak subdirektori) dan juga memberikan kesalahan / peringatan berikut:

rm: cannot remove directory: `/some/dir/.'
rm: cannot remove directory: `/some/dir/..'

Apa cara yang tepat untuk menghapus semua file dan folder yang tersembunyi dan tidak tersembunyi secara rekursif di direktori target tanpa menerima peringatan / kesalahan tentang .dan ..?

Jake Wilson
sumber

Jawaban:

40

Anda selalu dapat mengirim pesan kesalahan ke /dev/null

rm -rf /some/path/.* 2> /dev/null

Anda juga bisa saja

rm -rf /some/path/
mkdir /some/path/

... maka Anda tidak perlu repot dengan file tersembunyi sejak awal.

Evilsoup
sumber
2
Tetapi bagaimana jika saya hanya ingin menghapus file yang disembunyikan?
CMCDragonkai
@ CMCDragonkai yang seharusnya menjadi pertanyaan yang berbeda, tetapi Anda dapat menemukan solusi dalam jawaban Gilles ( rm ..?* .[!.]*harus melakukannya).
evilsoup
15
Tidak menghapus dan menciptakan kembali direktori menimbulkan risiko bahwa izin file tidak tepat setelah itu (terutama penting dalam lingkungan server). Siapa yang dapat membuat folder dengan izin yang sama seperti sebelumnya secara otomatis?
Yo Ludke
1
@YoLudke Anda sepenuhnya benar, dalam banyak situasi tidak masalah tetapi menghapus folder dan membuat ulang tidak secara semantik sama dengan mengosongkan folder itu; jadi berhati-hatilah melakukan itu!
Thomas
Menghapus direktori tidak selalu memungkinkan. Dalam kasus saya direktori adalah volume buruh pelabuhan, dan sementara saya dapat melakukan apapun yang saya inginkan di dalam volume, saya tidak dapat mengubah volume itu sendiri dari dalam wadah.
dovidweisz
84

*cocok dengan semua file non-dot, .[!.]*cocok dengan semua file dot kecuali .dan file yang namanya dimulai dengan .., dan ..?*cocok dengan semua file dot-dot kecuali ... Bersama-sama mereka mencocokkan semua file selain .dan ... Jika salah satu dari tiga pola ini tidak cocok dengan apa pun, itu akan berkembang dengan sendirinya; rm -ftidak peduli dengan argumen yang tidak ada, jadi ini tidak masalah.

rm -rf ..?* .[!.]* *

Anda juga bisa menggunakan find. Ini lebih kompleks tetapi memiliki keuntungan bekerja bahkan jika ada begitu banyak file yang wildcard di atas akan berkembang melampaui batas panjang baris perintah sistem Anda.

find . -name . -o -prune -exec rm -rf -- {} +

Anda mungkin merasa lebih jelas untuk menghapus dan membuat ulang direktori. Ini memiliki keuntungan (atau kelemahan, seperti halnya) untuk menghasilkan direktori kosong bahkan jika program lain secara bersamaan membuat file di direktori asli.

Gilles
sumber
8
Ini harus menjadi jawaban yang diterima, karena mencegah traversal orang tua dan kemungkinan penghapusan.
rbellamy
The findalternatif mengembalikan "sukses" bahkan jika beberapa file tidak berhasil dihapus; tidak baik untuk skrip.
Franklin Yu
Sehubungan dengan findperintah kedua Anda , halaman manual untuk status "Karena -hapus berarti -depth, Anda tidak dapat menggunakan -prune dan -hapus bersama-sama." - belum kamu gunakan -prune -delete?
Doktor J
@DoktorJ Memang, -prunetidak melakukan apa pun di sini. Dan saat membaca kembali saya melihat bahwa saya tidak menjawab pertanyaan dengan benar: Saya berusaha untuk tidak berulang, tetapi pertanyaan itu secara eksplisit meminta penghapusan rekursif. Saya sudah mengoreksi jawaban saya.
Gilles
2
@haylem Di zsh, Anda harus menulis .[^.]*alih-alih .[!.]*ketika subtitusi riwayat diaktifkan (yang secara default adalah kasus secara interaktif tetapi tidak dalam skrip), karena zsh mem !- parsing sebagai referensi riwayat. Tetapi di zsh Anda tidak akan membutuhkan itu sejak awal, Anda bisa menggunakan *(D)untuk memasukkan file dot (tanpa .atau ..) dalam kecocokan wildcard.
Gilles
21

Baru menyadari ini adalah cara paling nyaman di sebagian besar distro Linux:

ls -A1 | xargs rm -rf

dimana

-A= daftar semuanya kecuali . dan..

-1 = menempatkan setiap item dalam satu baris

godzillante
sumber
4
Kelemahan yang saya lihat adalah: Anda perlu 'cd' ke direktori untuk melakukan ini.
kumar
ls -A1 /your/path/ | xargs rm -rfharus berlaku
godzillante
tidak .. ini tidak membantu - Sebagai contoh: ls -A1 ~ / test / | xargs rm -rf perintah ini menghapus file yang saat ini saya 'cd ke' .. tidak dalam direktori ~ / test.
kumar
5
Ini tidak berfungsi jika ada nama file yang berisi kosong, baris baru, kutipan atau garis miring terbalik.
Stéphane Chazelas
1
-1 Karena komentar di atas. ↑↑↑↑↑↑↑↑
somethingSomething
15

Ubah dotglobopsi shell Anda dan gunakan *, atau gunakan sesuatu seperti find.

find somedir -mindepth 1 -delete
Ignacio Vazquez-Abrams
sumber
2
Atau Anda bisa dengan mudah rm -rf /some/dirdan kemudian membuat direktori kosong baru di tempatnya.
tripleee
Pilihan terbaik sejauh ini. Sangat aman karena Anda secara eksplisit menentukan jalur direktori.
Yanick Girouard
4

Ini seharusnya berfungsi seperti jawaban @Gilles tetapi lebih ringkas:

rm -rf {,.[!.],..?}*

atau

rm -rf dir/to/files/{,.[!.],..?}*

juga harus menambahkan ifuntuk penggunaan dalam skrip agar aman:

if [ -d "$DIR" ]; then
    rm -rf ${DIR}/{,.[!.],..?}*
fi
Paweł Prażak
sumber
1
Anehnya, sebagai bash alias di Ubuntu 16.04 LTS, jawaban sebelumnya tidak berfungsi. Namun alias cleandir='rm -rf {,.[!.],..?}*'demikian.
Steven Ventimiglia
3

Temukan adalah teman Anda.

find ! -name '.' ! -name '..' -delete

% find ! -name '.' ! -name '..'
./test
./test4
./test4/.test6
./test3
./.test5
./test2
% find ! -name '.' ! -name '..' -delete    
% find ! -name '.' ! -name '..'     
%             

Jika Anda ingin menggunakan pencarian secara rekursif lainnya di direktori Anda saat ini ($ PWD), maka tambahkan path tepat setelah findperintah; misalnya find /path ! -name '.' ! -name '..' -delete,. Jika Anda hanya ingin menurunkan njumlah direktori, maka gunakan -maxdepth nopsi tepat setelah /pathparameter.

Perintah di atas diuji pada sistem Ubuntu 13.04. Kemungkinan akan bekerja pada sistem linux modern lainnya.

laebshade
sumber
untuk menghapus semua direktori di direktori saat ini yang dapat Anda lakukanfind . ! -name '.' ! -name '..' -type d -delete
Andy
2

Apa cara yang tepat untuk menghapus semua file dan folder yang tersembunyi dan tidak tersembunyi secara rekursif di direktori target tanpa menerima peringatan / kesalahan. dan ..?

Dengan asumsi direktori yang bersangkutan ./dir, maka

rm -rf ./dir

akan menghapus semua file ./dir, termasuk file dan direktori tersembunyi, secara rekursif, dan termasuk ./dirdirektori itu sendiri.

Jika Anda tidak ingin menghapus direktori itu sendiri, maka Anda dapat membuatnya kembali setelahnya, atau menggunakannya

find ./dir -mindepth 1 -delete

atau jika Anda findtidak mendukung -delete,

find ./dir -mindepth 1 -depth -exec rm -rf {} ';'

Menggunakan -mindepth 1memungkinkan Anda untuk menyimpan direktori tingkat atas ./dir.

Kusalananda
sumber
ini harus ditandai sebagai jawaban terbaik
kitingChris
1

Saya sarankan Anda bereksperimen dengan

Turn- ON dots (file tersembunyi)

  • set dotglob

    shopt -s dotglob

Turn OFF titik

  • tidak disetel dotglob

    shopt -u dotglob

Metode ini bekerja persis seperti yang saya harapkan untuk perintah copy yang hilang direktori tersembunyi.

    shopt -s    dotglob
    cp    -rvn  ./$from/*  ./$too/
    shopt -u    dotglob

Jadi saya melakukan hapus (hapus), dan oops ...

    shopt -s    dotglob
    rm -fr ../message_splitter--044a/*
    shopt -u    dotglob

... itu juga berhasil!

Terpikir oleh saya bahwa Anda pembaca yang budiman tidak dapat melihat message_splitterdirektori. Cara apa pun itu memiliki .svnfolder yang perlu dihapus, dan disalin ke.

Dari manhalaman ...

dotglob Jika diset, bash menyertakan nama file yang diawali dengan `. ' dalam hasil ekspansi pathname.

referensi:

akan
sumber
-2

Coba kode ini:

Dirlist=``find /some/path/ -type d -name '.[^.]*'`
for HiddenDir in $Dirlist
do
    rm -rf $HiddenDir
done
siz
sumber