Menghapus direktori kosong secara rekursif di Windows

94

Saya memiliki direktori di mesin Windows 7 saya yang memiliki ratusan atau ribuan direktori. Beberapa dari mereka memiliki file, beberapa tidak. Saya ingin menghapus semua direktori yang kosong.

Melihat perintah DOS del dan rmdir, sepertinya Anda tidak dapat melakukannya secara rekursif tanpa menghapus semua file. Apakah ada cara untuk melakukan ini dari baris perintah?

Mohlsen
sumber
Saya kagum tidak ada jawaban sederhana untuk pertanyaan ini.
billpg
@billpg: sederhana seperti itu bisa mendapatkan: xcopy FROMDIR TODIR /s. Lihat jawaban SO ini: stackoverflow.com/a/14742810
eckes
1
XCOPY menghapus direktori?
billpg
1
Itu dapat dilakukan dengan mudah menggunakan ROBOCOPY. Lihat jawaban saya di bawah untuk detailnya.
Varun Sharma

Jawaban:

116

Anda dapat menggunakan utilitas Hapus Direktori Kosong .

Atau Anda dapat menggunakan file batch satu-liner ini (dari DownloadSquad ):

for /f "delims=" %d in ('dir /s /b /ad ^| sort /r') do rd "%d"

(jika digunakan di dalam file batch, ganti %ddengan %%d)

Ini berfungsi karena rdtidak akan menghapus direktori yang berisi file.

pemarah
sumber
6
PS Saya sarankan Anda mencoba alat berbasis GUI terlebih dahulu, sebelum mencoba perintah baris perintah yang berpotensi menghapus semua file.
caliban
1
Pastikan itu benar-benar kosong. Desktop.ini tersembunyi masih dianggap sebagai file. sama seperti thumbs.db. Jika Anda ingin memverifikasi apakah ini berfungsi, buat direktori pengujian dengan direktori di dalamnya yang kosong dan terisi. Berhasil, saya sudah memverifikasi.
caliban
1
Ya. Berhasil. Kesalahanku.
EBGreen
8
untuk / f% d di ( 'dir / s / b') jangan rmdir "% d" harus bekerja sebagai rmdir tidak dapat menghapus non-kosong folder
seanyboy
1
Lihatlah stackoverflow.com/a/34025977/694360 untuk mengetahui cara menambahkan fungsionalitas ini ke menu konteks.
mmj
49

Anda juga dapat menggunakan ROBOCOPY. Ini sangat sederhana dan juga dapat digunakan untuk menghapus folder kosong di dalam hierarki besar.

ROBOCOPY folder1 folder1 /S /MOVE

Di sini baik sumber dan tujuan folder1, karena Anda hanya perlu menghapus folder kosong, alih-alih memindahkan file lain ke folder lain. /Sopsi adalah untuk melewatkan penyalinan (memindahkan, dalam kasus di atas) folder kosong. Ini juga lebih cepat karena file dipindahkan di dalam drive yang sama.

Varun Sharma
sumber
1
Sihir. Jadi ini memindahkan semua folder non-kosong ke lokasi yang sama dengan yang sudah ada (begitu juga tidak ada?), Dan melompati folder kosong? Tetapi kemudian: mengapa melewatkan mereka akan menghasilkan penghapusan? Dan bukankah ini memindahkan folder bersarang ke folder1? Menakutkan, kecuali diuji dengan baik.
Arjan
3
@Arjan saya telah mengujinya, dan berfungsi dengan sempurna !. Untuk memahami cara kerjanya, itu seperti memindahkan semua file ke lokasi yang berbeda, kecuali folder kosong, dan kemudian menghapus folder kosong yang ditinggalkan. /MOVEmenyalin file terlebih dahulu, dan kemudian menghapus file sumber setelah menyalin. Jadi, seperti /Syang digunakan, ini menyalin folder yang tidak kosong ke tujuan (folder yang sama dalam kasus di atas). Kemudian, itu menghapus folder kosong (seperti, berpikir bahwa folder kosong telah disalin). Tidak, itu tidak memindahkan folder bersarang ke dalam folder1, karena ROBOCOPY memindahkan folder secara rekursif.
Varun Sharma
3
bahkan bekerja dengan jalur UNC (setidaknya pada win7)! Cemerlang!
Arioch 'The
2
Ini adalah solusi yang sangat elegan tanpa memerlukan perangkat lunak pihak ketiga. Terima kasih!
Marcus Mangelsdorf
1
Ini hanya melakukan keajaibannya dan bekerja dengan sempurna. Terima kasih!
CharleyDC5
15

Karena Cygwin dilengkapi dengan GNU find, Anda dapat melakukan ini:

find . -type d -empty -delete

Atau untuk menghindari kebisingan saat folder tidak ada lagi:

find . -type d -empty -execdir rmdir {} +
Taji
sumber
Ini sekarang juga dapat dilakukan dengan menggunakan Windows 10 Bash.
Maret Maret
Untuk instal Windows 10 saya ( find . -type d -empty -delete) ini gagal dari command prompt dengan kesalahan berikut:FIND: Parameter format not correct
ImpressTheNet Web Developer
7

Utilitas gratis EmptyFolderNuker melakukan ini dengan baik, dari folder dasar pilihan Anda. Itu juga menghapus direktori-direktori itu hanya berisi sub-direktori kosong.

Rob Kam
sumber
1
File batch satu-liner tidak berfungsi untuk saya (saya mendapatkan kesalahan "%% d tidak terduga saat ini."), Dan program Remove Empty Directories tidak akan menginstal (dikatakan di halaman tertaut bahwa itu bukan kompatibel dengan Windows 7). Program ini bekerja seperti pesona.
Phoenix
1
Seperti yang ditulis oleh user36580 di bawah ini, "sepertinya Anda menjalankan langsung dari baris perintah. Dalam hal ini, ubah double %% menjadi satu%"
Lachlan McD.
1
Saya suka ini melalui versi baris perintah murni karena memungkinkan Anda untuk melihat pratinjau hal-hal yang dihapus. Anda selalu dapat memanggilnya dari baris perintah menggunakan "%~dp0\EmptyFolderNuker.exe" %cd%.
Jeroen Wiert Pluimers
1
@ rob-kam URL untuk "EmptyFolderNuker" tidak tersedia lagi.
PeterCo
@PeterCo Terima kasih, perbaiki sekarang.
Rob Kam
0

Jika Anda telah menginstal Cygwin , Anda dapat melakukan ini:

find -type d -exec rmdir {} \;
Anthony Giorgio
sumber
4
Belum tentu. Itu mungkin tidak menghapus direktori dengan hanya subdirektori kosong. Anda mungkin harus membalikkannya. temukan -type d -print0 | tac | xargs -0 rmdir
Ryan Thompson
Saya tidak pernah tahu tentang "tac" sebelumnya. Benar-benar bagus!
Anthony Giorgio
1
Atau gunakan . The pilihan memberitahu untuk melakukan sesuatu seperti membalik urutan output - ia pergi ke tingkat direktori terdalam pertama, kemudian bekerja jalan kembali. find (starting-directory) -depth -type d ...-depthfind
G-Man
0

Jika Anda bekerja di emacs (membuat platform ini agnostik), berikut ini berfungsi:

(defun *-delete-empty-directories (root-directory)
  "Recursively delete empty directories in ROOT-DIRECTORY.

When called from dired, `dired-current-directory' is used for
ROOT-DIRECTORY."

  ;; Interface
  (interactive (list (if (eq major-mode 'dired-mode)
                         (expand-file-name (dired-current-directory))
                       (read-from-minibuffer "Root directory: "))))
  (when (or (null root-directory) (string= "" root-directory))
    (user-error "No root directory provided"))
  (when (called-interactively-p 'interactive)
    (unless (yes-or-no-p (format "Delete all non-empty directories in `%s'? "
                                 root-directory))
      (user-error "Directory `%s' has been left untouched" root-directory)))

  ;; Implementation
  (require 'f)
  (let ((entries (f-directories root-directory)))
    (while entries
      (let ((curdir (car entries)))
        (when (f-directories curdir)
          (*-delete-empty-directories curdir))
        (unless (f-entries curdir)
          (delete-directory curdir)
          (message "Directory deleted: `%s'" curdir))
        (setq entries (cdr entries)))))
Sean Allred
sumber
... Tolong beritahu saya Anda tidak perlu mengetik semua ini untuk mencapai ini di emacs.
Hashim
1
@Hashim Idenya adalah bahwa Anda telah mendefinisikannya di init Anda dan kemudian terikat pada kunci. Secara teknis saya bisa memilikinya terikat Djika saya mau, tetapi karena saya tidak memiliki kebutuhan bersama untuk ini, semua saya harus mengetik adalah M-x *ded RETdan dilakukan. (Jika saya memang harus mengetik ini setiap waktu, Anda benar bahwa itu tidak masuk akal - untungnya bukan itu masalahnya.)
Sean Allred
Cukup adil, itu terdengar lebih masuk akal.
Hashim
Apakah M-x *ded RETada signifikansi atau acak? Jika yang terakhir, bagaimana Anda melacak semua pintasan yang telah Anda tetapkan emacs? Apakah menghafal sudah mencukupi atau apakah Anda harus mencarinya?
Hashim
1
@Hashim *dedadalah singkatan untuk nama fungsi lengkap *-delete-empty-directories. Banyak mesin penyelesaian (seperti ivy, yang saya gunakan) memahami pencocokan fuzzy semacam ini. Adapun menjaga mereka hafal ... Saya tidak perlu. Fungsi-fungsi yang telah saya definisikan semuanya dimulai dengan *sehingga saya dapat dengan mudah menemukannya jika mereka tidak terikat pada kunci. Kalau tidak, emacs sendiri akan memberi tahu saya jika ada cara yang lebih cepat untuk memanggil fungsi. Jika semuanya gagal, selalu ada apropos.
Sean Allred
0

Menggabungkan posting Gareth dan G-Man:

find . -depth -type d -empty -execdir rmdir {} +

Sunting: Tapi itu memberikan kesalahan keamanan karena 'C' di PATH var saya ... jadi alih-alih:

$find . -depth -type d -empty | while read dir; do (rmdir -v $dir); done

Saya tidak menggunakan xargs karena tampaknya memiliki batas jalur input (sekitar 1024 baris, saya kira?), Sedangkan

 while read x; do (command $x); done

terus berjalan selama ia memiliki input. Biarkan flag verbose '-v' jika Anda tidak ingin melihat hasilnya dan / atau ingin itu berjalan lebih cepat.

skeetastax
sumber
0

Hmmm ... solusi mungkin lebih sederhana:

for /d /r %d in (*.*) do rd "%d"

Mulai ini dari folder yang Anda ingin folder kosong dihapus.

/ d - akan bekerja pada folder, bukan file / r - akan mengembalikan subdir

Daniel Mošmondor
sumber