Rekursives Löschen leerer Verzeichnisse in Windows

93

Ich habe ein Verzeichnis auf meinem Windows 7-Computer, das Hunderte, wenn nicht Tausende von Unterverzeichnissen enthält. Einige von ihnen haben Dateien, andere nicht. Ich möchte alle leeren Verzeichnisse löschen.

Wenn Sie den DOS-Befehl del und rmdir betrachten, sieht es nicht so aus, als könnten Sie dies rekursiv tun, ohne alle Dateien zu löschen. Gibt es eine Möglichkeit, dies von der Befehlszeile aus zu tun?

mohlsen
quelle
Ich bin erstaunt, dass es keine einfache Antwort auf diese Frage gibt.
billpg
@billpg: einfach , wie es bekommen kann: xcopy FROMDIR TODIR /s. Siehe diese SO-Antwort: stackoverflow.com/a/14742810
eckes
1
XCOPY löscht Verzeichnisse?
billpg
1
Mit ROBOCOPY ist dies problemlos möglich. Siehe meine Antwort unten für Details.
Varun Sharma

Antworten:

115

Sie können das Dienstprogramm Leere Verzeichnisse entfernen verwenden .

Alternativ können Sie diese einzeilige Batch-Datei (von DownloadSquad ) verwenden:

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

(falls in einer Batch-Datei verwendet, ersetzen %ddurch %%d)

Dies funktioniert, weil rdein Verzeichnis, das Dateien enthält, nicht entfernt wird.

Kaliban
quelle
6
PS Ich schlage vor, dass Sie zuerst das GUI-basierte Tool ausprobieren, bevor Sie Befehlszeilenbefehle ausführen, mit denen möglicherweise alle Dateien gelöscht werden können.
Caliban
1
Stellen Sie sicher, dass es wirklich leer ist. Eine versteckte desktop.ini wird weiterhin als Datei betrachtet. wie ein thumbs.db. Wenn Sie überprüfen möchten, ob dies funktioniert, erstellen Sie ein Testverzeichnis mit Verzeichnissen, die leer und gefüllt sind. Ich habe bestätigt, dass es funktioniert.
Caliban
1
Ja. Es klappt. Mein Fehler.
EBGreen
8
für / f% d in ('dir / s / b') do rmdir "% d" sollte funktionieren, da rmdir einen nicht leeren Ordner nicht entfernen kann
seanyboy
1
Informationen zum Hinzufügen dieser Funktionalität zum Kontextmenü finden Sie unter stackoverflow.com/a/34025977/694360 .
Mmj
49

Sie können auch ROBOCOPY verwenden. Es ist sehr einfach und kann auch zum Löschen leerer Ordner innerhalb einer großen Hierarchie verwendet werden.

ROBOCOPY folder1 folder1 /S /MOVE

Hier sind sowohl Quelle als auch Ziel folder1, da Sie nur leere Ordner löschen müssen, anstatt andere Dateien in einen anderen Ordner zu verschieben. /SDie Option besteht darin, das Kopieren (Verschieben, in diesem Fall) von leeren Ordnern zu überspringen. Es ist auch schneller, wenn die Dateien in dasselbe Laufwerk verschoben werden.

Varun Sharma
quelle
1
Magie. Dadurch werden alle nicht leeren Ordner an denselben Speicherort verschoben, an dem sie sich bereits befanden (also nichts?), Und leere Ordner werden übersprungen. Aber dann: Warum führt das Überspringen zum Löschen? Und würde dies nicht verschachtelte Ordner verschieben folder1? Unheimlich, wenn nicht gut getestet.
Arjan
3
@Arjan Ich habe es getestet und es funktioniert einwandfrei !. Um zu verstehen, wie es funktioniert, werden alle Dateien an einen anderen Speicherort verschoben, mit Ausnahme von leeren Ordnern. Anschließend werden die verbleibenden leeren Ordner gelöscht. /MOVEkopiert zuerst die Dateien und löscht dann die Quelldatei nach dem Kopieren. So, wie /Ses verwendet wird, kopiert es die nicht leeren Ordner zum Ziel (derselbe Ordner im obigen Fall). Dann löscht es die leeren Ordner (es wird angenommen, dass leere Ordner bereits kopiert wurden). Nein, verschachtelte Ordner werden nicht verschoben folder1, da ROBOCOPY Ordner rekursiv verschiebt.
Varun Sharma
3
es funktioniert sogar mit UNC-Pfaden (zumindest auf win7)! Brillant !
Arioch 'The
2
Dies ist eine sehr elegante Lösung, ohne dass Software von Drittanbietern benötigt wird. Danke!
Marcus Mangelsdorf
1
Dies hat einfach seine Magie und perfekt funktioniert. Vielen Dank!
CharleyDC5
15

Da Cygwin mit GNU find geliefert wird, können Sie dies tun:

find . -type d -empty -delete

Oder um das Rauschen zu vermeiden, wenn ein Ordner nicht mehr vorhanden ist:

find . -type d -empty -execdir rmdir {} +
Gaff
quelle
Dies ist jetzt auch mit Windows 10 Bash möglich.
März,
Bei meiner Installation von Windows 10 find . -type d -empty -deleteschlägt this ( ) an der Eingabeaufforderung mit folgendem Fehler fehl:FIND: Parameter format not correct
ImpressTheNet Web Developer
7

Das kostenlose Dienstprogramm EmptyFolderNuker erledigt dies in einem Basisordner Ihrer Wahl. Es werden auch die Verzeichnisse entfernt, die nur leere Unterverzeichnisse enthalten.

Rob Kam
quelle
1
Die einzeilige Batch-Datei hat bei mir nicht funktioniert (ich erhalte die Fehlermeldung "%% d war zu diesem Zeitpunkt unerwartet."), Und das Programm "Leere Verzeichnisse entfernen" wird nicht installiert (auf der verlinkten Seite heißt es, dass dies nicht der Fall ist kompatibel mit Windows 7). Dieses Programm hat wie ein Zauber gewirkt.
Phoenix
1
Wie user36580 weiter unten schrieb: "Es ist wahrscheinlich, dass Sie direkt über die Befehlszeile ausgeführt werden. Ändern Sie in diesem Fall das doppelte %% in ein einzelnes%"
Lachlan McD.
1
Mir gefällt dies über die reine Befehlszeilenversion, da Sie eine Vorschau der gelöschten Elemente anzeigen können. Sie können es jederzeit über die Befehlszeile mit aufrufen "%~dp0\EmptyFolderNuker.exe" %cd%.
Jeroen Wiert Pluimers
1
@ rob-kam Die URL für "EmptyFolderNuker" ist nicht mehr verfügbar.
PeterCo
@PeterCo Danke, jetzt behoben.
Rob Kam
0

Wenn Sie Cygwin installiert haben, können Sie dies tun:

find -type d -exec rmdir {} \;
Anthony Giorgio
quelle
4
Nicht unbedingt. Dadurch werden möglicherweise keine Verzeichnisse mit nur leeren Unterverzeichnissen gelöscht. Möglicherweise müssen Sie es umkehren. find -type d -print0 | tac | xargs -0 rmdir
Ryan Thompson
Ich wusste noch nie von "tac". Das ist wirklich schick!
Anthony Giorgio
1
Oder benutze . Die Option fordert dazu auf, die Reihenfolge der Ausgabe umzukehren. Sie wechselt zuerst in die tiefsten Verzeichnisebenen und arbeitet sich dann wieder nach oben. find (starting-directory) -depth -type d ...-depthfind
G-Man,
0

Wenn Sie in Emacs arbeiten (wodurch diese Plattform nicht von der Konkurrenz abhängig ist), funktioniert Folgendes:

(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
quelle
... Bitte sagen Sie mir, dass Sie dies nicht alles eingeben müssten, um dies in Emacs zu erreichen.
Hashim
1
@Hashim Die Idee ist, dass Sie es in Ihrem Init definiert und dann an einen Schlüssel gebunden haben. Technisch könnte ich mich daran binden lassen, Dwenn ich wollte, aber da ich keinen gemeinsamen Bedarf dafür habe, muss ich nur tippen M-x *ded RETund loslegen. (Wenn ich das tatsächlich jedes Mal tippen müsste, hast du absolut Recht, dass es absurd wäre - zum Glück ist das nicht der Fall.)
Sean Allred
Fair genug, das klingt plausibler.
Hashim
Hat M-x *ded RETes irgendeine Bedeutung oder ist es zufällig? Wie können Sie in letzterem Fall alle Verknüpfungen nachverfolgen, die Sie zugewiesen haben emacs? Reicht das Auswendiglernen aus oder müssen Sie es nachschlagen?
Hashim
1
@Hashim *dedist eine Abkürzung für den vollständigen Funktionsnamen *-delete-empty-directories. Viele Vervollständigungs-Engines (wie das von mir verwendete Ivy) verstehen diese Art von Fuzzy-Matching. Ich muss sie einfach nicht auswendig lernen. Die von mir definierten Funktionen beginnen mit, *damit ich sie leicht finden kann, wenn sie nicht an einen Schlüssel gebunden sind. Andernfalls teilt mir Emacs selbst mit, ob es eine schnellere Methode zum Aufrufen der Funktion gab. Wenn alles andere fehlschlägt, gibt es immer apropos.
Sean Allred
0

Zusammenfassung der Beiträge von Gareth und G-Man:

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

Edit: Aber das gab einen Sicherheitsfehler wegen 'C' in meinem PATH var ... also stattdessen:

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

Ich verwende keine xargs, da es anscheinend ein Eingabezeilenlimit gibt (von ungefähr 1024 Zeilen, denke ich?), Wohingegen

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

macht einfach so lange weiter, wie es Input hat. Lassen Sie das ausführliche Flag "-v" weg, wenn Sie die Ergebnisse nicht sehen und / oder schneller ausführen möchten.

Skeetastax
quelle
0

Hmmm ... vielleicht noch einfachere Lösung:

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

Starten Sie dies aus dem Ordner, in dem leere Ordner gelöscht werden sollen.

/ d - Arbeitet mit Ordnern, nicht mit Dateien. / r - Wiederholt Unterverzeichnisse

Daniel Mošmondor
quelle