Cara menghapus semua direktori .svn dari direktori aplikasi saya

192

Salah satu misi alat ekspor yang saya miliki di aplikasi saya, adalah untuk membersihkan semua .svndirektori dari pohon direktori aplikasi saya. Saya mencari perintah rekursif di shell Linux yang akan melintasi seluruh pohon dan menghapus .svnfile.

Saya tidak menggunakan ekspor, karena skrip ini akan digunakan untuk beberapa nama file / direktori lain yang tidak terkait dengan SVN. Saya mencoba sesuatu seperti:

find . -name .svn | rm -fr

Itu tidak berhasil ...

Itay Moav -Malimovka
sumber
3
Perintah Anda harus bekerja jika Anda menggunakan 'xargs rm -rf'
Peter van der Heijden
1
Anda mungkin juga ingin memodifikasi perintah hapus "rm -rfi" hanya untuk memastikan Anda yakin Anda ingin menghapus direktori.
bedwyr
Jangan gunakan xargs .. Anda akan mengalami masalah dengan direktori yang memiliki ruang di dalamnya, dll. Gunakan find seperti yang dijelaskan di bawah ini.
John Hunt

Jawaban:

438

Coba ini:

find . -name .svn -exec rm -rf '{}' \;

Sebelum menjalankan perintah seperti itu, saya sering suka menjalankan ini terlebih dahulu:

find . -name .svn -exec ls '{}' \;
Greg
sumber
43
Anda mungkin perlu memasukkan {} ke dalam satu kutipan jika ada ruang atau karakter seperti itu dalam direktori: find . -name .svn -exec rm -rf '{}' \;
mtoloo
38
Tes ini berfungsi lebih baik di bash saya:find . -name .svn -exec echo {} \;
Fedir RYKHTIK
6
Menjalankan echo / ls pertama adalah sentuhan 'pro' untuk jawaban ini. Siapa pun yang bodoh dapat merusak sistem.
John Hunt
6
apa yang {} \;dilakukan?
Jon Mitten
3
Dengan menjalankan perintah kedua termasuk ls, saya mendapatkan entries prop-base props text-base tmpoutput ...
Rasoul
51

Apa yang Anda tulis mengirim daftar nama file (dan jalur) yang dipisahkan baris baru rm, tetapi rm tidak tahu apa yang harus dilakukan dengan input itu. Itu hanya mengharapkan parameter baris perintah.

xargs mengambil input, biasanya dipisahkan oleh baris baru, dan menempatkannya di baris perintah, jadi menambahkan xargs membuat apa yang Anda kerjakan:

find . -name .svn | xargs rm -fr

xargscukup cerdas sehingga hanya akan memberikan argumen rmsebanyak yang dapat diterima. Jadi, jika Anda memiliki sejuta file, ia dapat berjalan rm1.000.000 / 65.000 kali (jika shell Anda dapat menerima 65.002 argumen di baris perintah {65k file +1 untuk rm + 1 untuk -fr}).

Seperti yang ditunjukkan orang dengan mahir, berikut ini juga berfungsi:

find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf

Dua -execformulir pertama memanggil rmuntuk setiap folder yang dihapus, jadi jika Anda memiliki 1.000.000 folder, rmakan dipanggil 1.000.000 kali. Ini tentu kurang ideal. Implementasi yang lebih baru rmmemungkinkan Anda untuk menyimpulkan perintah dengan +indikasi yang rmakan menerima argumen sebanyak mungkin:

find . -name .svn -exec rm -rf {} +

Versi find / xargs terakhir menggunakan print0, yang membuat find menghasilkan output yang digunakan \0sebagai terminator daripada baris baru. Karena sistem POSIX mengizinkan karakter apa pun kecuali \0dalam nama file, ini benar-benar cara paling aman untuk memastikan bahwa argumen diteruskan dengan benar rmatau aplikasi dijalankan.

Selain itu, ada -execdiryang akan mengeksekusi rmdari direktori di mana file itu ditemukan, bukan di direktori dasar dan -depthyang akan mulai lebih dalam.

Kaleb Pederson
sumber
31

Tidak perlu untuk pipa, xarg, exec, atau apa pun:

find . -name .svn -delete

Sunting: Hanya bercanda, jelas -deletememanggil di unlinkat()bawah tenda, sehingga berperilaku seperti unlinkatau rmdirdan akan menolak untuk beroperasi pada direktori yang berisi file.

AB
sumber
54
Satu masalah, -deletetidak akan menyentuh direktori jika berisi file.
Xeoncross
2
Tidak ada -forceatau rekursif bendera untuk -deletepredikat, jadi jawaban ini tidak berguna. Dengan demikian, itu kembali ke |xargs rm -rf, yang kurang jelek untuk mengetik kemudian -execdengan penampung yang buruk dan titik koma: -exec rm -rf '{}' \;.
Tomasz Gandor
13

Sudah ada banyak jawaban yang diberikan untuk menghapus direktori .svn. Tetapi saya ingin menambahkan, bahwa Anda dapat menghindari direktori ini dari awal, jika Anda melakukan ekspor alih-alih checkout:

svn export <url>
Mnementh
sumber
+1, tidak perlu mengulang ini ketika sudah built-in ke svn.
Powerlord
1
Satu-satunya masalah yang saya lihat dengan pendekatan ini adalah jika Anda ingin menyimpan file yang tidak berversi dalam ekspor. Dari dokumen svn, "Semua perubahan lokal akan dipertahankan, tetapi file yang tidak di bawah kontrol versi tidak akan disalin."
raidfive
@raidfive: Biasanya saya lebih suka memiliki semua file yang relevan di bawah kontrol versi, bahkan perpustakaan yang digunakan, sehingga proyek bekerja di luar kotak. File tidak berversi dalam pengaturan ini adalah biner yang dikompilasi, yang dibuat kembali oleh tujuan di buildfile. Tapi Anda benar, jika proyek Anda bergantung pada file yang tidak di bawah kontrol versi, ekspor tidak akan berfungsi.
Mnementh
tapi ... aku butuh jawaban yang lebih umum. .Svn hanyalah contoh yang paling umum, saya perhatikan dalam pertanyaan itu.
Itay Moav -Malimovka
12

Jika Anda tidak suka melihat banyak

find: `./.svn': No such file or directory

peringatan, lalu gunakan -depthsakelar:

find . -depth -name .svn -exec rm -fr {} \;
lazy1
sumber
10

Di Windows, Anda dapat menggunakan skrip registri berikut untuk menambahkan "Hapus Folder SVN" ke menu konteks klik kanan Anda. Jalankan di direktori mana pun yang berisi file-file sial itu.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="Delete SVN Folders"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
@="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""
Nathan Taylor
sumber
Trik rapi. Tidak membantu untuk OP, tetapi +1 karena saya terkesan!
rrhartjr
ini luar biasa. Terima kasih. Aku tahu ini super tua, tapi terserahlah. saya tetap menyukainya.
Anthony
9

Anda hampir memilikinya. Jika Anda ingin meneruskan output dari perintah sebagai parameter ke yang lain, Anda harus menggunakan xargs. Menambahkan -print0memastikan skrip dapat menangani jalur dengan spasi putih:

find . -type d -name .svn -print0|xargs -0 rm -rf
soulmerge
sumber
2
Bagi beberapa orang, apa yang berhasil pada akhirnya dapat ditemukan. -nama .svn | xargs rm -rf Versi Anda memberi saya arah, terima kasih
Itay Moav -Malimovka
4
find . -name .svn |xargs rm -rf
Itay Moav -Malimovka
sumber
4

Sebagai masalah penting, ketika Anda ingin memanfaatkan shell untuk menghapus folder .svn Anda perlu argumen -depth untuk mencegah perintah menemukan memasuki direktori yang baru saja dihapus dan menampilkan pesan kesalahan seperti misalnya

"find: ./.svn: No such file or directory"

Akibatnya, Anda dapat menggunakan perintah find seperti di bawah ini:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
fatihk
sumber
Inilah yang saya cari dan harus menjadi jawaban yang benar.
luckytaxi
3

Coba ini:

find . -name .svn -exec rm -v {} \;

Baca lebih lanjut tentang perintah find di developerWorks .

Edward Dale
sumber
2

Atau, jika Anda ingin mengekspor salinan tanpa mengubah copy yang berfungsi, Anda dapat menggunakan rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export
pimlottc
sumber
1
Atau gunakan svn export / path / to / repository, yang pada dasarnya melakukan hal yang sama.
Kaleb Pederson
Penulis secara khusus mengatakan dia tidak ingin menggunakan svn; mungkin lingkungan targetnya belum diinstal svn.
pimlottc