Wie kann ich alle leeren Verzeichnisse in einem Teilbaum entfernen? Ich habe so etwas benutzt
find . -type d -exec rmdir {} 2>/dev/null \;
Ich muss jedoch mehrere Male ausgeführt werden, um Verzeichnisse zu entfernen, die nur leere Verzeichnisse enthalten. Außerdem ist es ziemlich langsam, besonders unter Cygwin.
Antworten:
find
Dieser Befehl kombiniert GNU- Optionen und Prädikate und sollte folgende Aufgaben erfüllen:-type d
beschränkt sich auf Verzeichnisse-empty
beschränkt sich auf leere-delete
Entfernt jedes VerzeichnisDer Baum wird von den Blättern entfernt, ohne dass dies angegeben
-depth
werden muss-delete
.quelle
-delete
impliziert bereits,-depth
so dass Sie das nicht manuell angeben müssen.-mindepth 1
hier hinzufügen , um zu verhindern, dass das Startverzeichnis selbst gelöscht wird, wenn es leer wäre.!
hat eine besondere Bedeutung für die Schale. Du musst entkommen. Sowas wie: sollte\! -name 'Completed'
kurz vorher-delete
klappen. Oder Sie legen einfach eine Markierungsdatei in dieses Verzeichnis.Listen Sie die tief verschachtelten Verzeichnisse zuerst auf.
(Beachten Sie, dass die Umleitung für den
find
gesamten Befehl gilt , nicht nur fürrmdir
. Eine Umleitung nur fürrmdir
würde zu einer erheblichen Verlangsamung führen, da Sie eine Zwischen-Shell aufrufen müssten.)Sie können die Ausführung
rmdir
in nicht leeren Verzeichnissen vermeiden, indem Sie das zu-empty
suchende Prädikat übergeben. GNU find testet das Verzeichnis, wenn es darum geht, den Befehl auszuführen, so dass Verzeichnisse, die gerade geleert wurden, aufgenommen werden.Eine andere Möglichkeit zur Beschleunigung besteht darin, die
rmdir
Aufrufe zu gruppieren . Beide dürften spürbar schneller sein als das Original, insbesondere unter Cygwin. Ich erwarte keinen großen Unterschied zwischen diesen beiden.Welche Methode schneller ist, hängt davon ab, wie viele nicht leere Verzeichnisse Sie haben. Sie können nicht
-empty
mit Methoden zum Gruppieren von Aufrufen kombinieren , da dann die Verzeichnisse, die nur leere Verzeichnisse enthalten, zum Zeitpunkt derfind
Betrachtung nicht leer sind.Eine andere Methode wäre, mehrere Durchläufe durchzuführen. Ob dies schneller ist, hängt unter anderem davon ab, ob die gesamte Verzeichnishierarchie zwischen den
find
Durchläufen im Festplatten-Cache verbleiben kann .Alternativ können Sie auch zsh verwenden. Das Glob-Qualifikationsmerkmal
F
stimmt mit nicht leeren Verzeichnissen/^F
überein , entspricht also leeren Verzeichnissen. Verzeichnisse, die nur leere Verzeichnisse enthalten, können nicht so einfach abgeglichen werden.(Dies wird beendet, wenn
rmdir
eine leere Befehlszeile empfangen wird.)quelle
-p
? Ich hätte nicht gedacht, dass es einen Unterschied machen würde.-empty
sollte mit diesem funktionieren (obwohl ich nicht genau weiß, wie viel es gewinnen wird). Und sehr, sehr trivial, da Sie wahrscheinlich nicht entfernen möchten.
, verwenden-mindepth 1
.-depth
Argument übersehen , wasrmdir -p
nutzlos macht . Ich habe meinen Kommentar bereits geändert. Die 90er Jahre waren mein ursprünglicher Versuch; es gibt hier nichts überraschendes.rmdir
Befehlsaufruf zumindest mit GNU find mit folgendem Befehl entfernen können :find . -depth -type d -empty -delete
Wenn Sie nur eine
-p
auf Ihre heftenrmdir
, wird das in einem Durchgang funktionieren. Es wird nicht schön oder optimal sein, aber es sollte alles bekommen. Dadurch wird rmdir angewiesen, alle nicht leeren übergeordneten Verzeichnisse des zu entfernenden zu entfernen.Sie können ein wenig sparen, indem Sie den
-empty
zu suchenden Test hinzufügen , damit es nicht um nicht leere Verzeichnisse geht.quelle
find . -depth -type d -exec rmdir {} +
ist die einfachste und standardkonforme Antwort auf diese Frage.
Die anderen hier gegebenen Antworten hängen leider alle von herstellerspezifischen Verbesserungen ab, die nicht auf allen Systemen vorhanden sind.
quelle
find . -type d -printf "%d %p\n" |\ sort -nr |\ perl -pe 's/^\d+\s//;' |\ while read dir; do \ (rmdir "$dir" > /dev/null 2>&1); \ done
So funktioniert das:
rmdir
die Liste einzeln ausquelle
Ich verwende diese Aliase für häufig verwendete
find
Befehle, insbesondere wenn ich mit dupeguru den Speicherplatz aufräumt , wobei das Entfernen von Duplikaten zu einer Menge leerer Verzeichnisse führen kann.Kommentare im Inneren,
.bashrc
damit ich sie später nicht vergesse, wenn ich sie anpassen muss.quelle
rm -r */
Befehl funktionierte leicht für mich.rm
sollte erfordern-f
, Verzeichnisse mit Dateien mit Gewalt zu entfernen.rm -r
sollte nur leere Verzeichnisse entfernen. Ich bin offen, warum das falsch sein könnte. Dies sollte auch Dateien belassen, da*/
nur Ordner betrachtet werden.quelle
rm
es in erster Linie zum Entfernen von Dateien gedacht ist. Während*/
nur Verzeichnisse übereinstimmt, habe ich keine Ahnung , was es tiefere Ebene tut auf. Ich kann mir auch vorstellen, dass es nur auf einigen Systemen funktioniert.