Wie lösche ich alle leeren Verzeichnisse in einem Verzeichnis über die Befehlszeile?

58

Angenommen, ich habe ein Verzeichnis mit dem Namen foo/. Dieser Ordner enthält Unterverzeichnisse. Wie kann ich alle leeren Verzeichnisse in einem Befehl löschen?

justingrif
quelle

Antworten:

119

Versuchen Sie diesen Befehl:

find . -empty -type d -delete

Der findBefehl wird verwendet, um nach Dateien / Verzeichnissen zu suchen, die mit einem bestimmten Suchkriterium aus dem angegebenen Pfad übereinstimmen, in diesem Fall dem aktuellen Verzeichnis (daher das .).

Die -emptyOption gilt für alle Dateien und Verzeichnisse, die leer sind.

Die -type dOption gilt für den angegebenen Dateityp . in diesem Fall dsteht für den Typ Dateiverzeichnis .

Die -deleteOption ist die auszuführende Aktion und gilt für alle in der Suche gefundenen Dateien.

Rechnung
quelle
Ich denke, dies ist der einfachste Weg, also werde ich fortfahren und dies als beantwortet markieren.
Justingrif
Hey Bill, ich habe versucht, eine weitere ähnliche Frage zu stellen, die ich nicht beantworten konnte, weil sie besagt, dass es sich um eine Betrug handelt. Ich hatte gehofft, dass Sie mir hier möglicherweise antworten können. Angenommen, ich wollte dasselbe wie oben tun, aber alle Verzeichnisse entfernen, ob sie leer sind oder nicht.
Justingrif
3
Die Art und Weise Sie Verzeichnisse entfernen würde, unabhängig davon , ob sie leer sind, geben Sie den folgenden Befehl ein : rm -rf <directory-name>. Dadurch werden das Verzeichnis sowie der gesamte Inhalt einschließlich der Dateien und Unterverzeichnisse entfernt. Die -rOption bedeutet, dass rekursiv gelöscht wird, während der -fBefehl bedeutet, dass vor dem Löschen keine Eingabeaufforderung angezeigt wird. Wenn Sie jedoch vor dem Löschen eines Verzeichnisses / einer Datei dazu aufgefordert werden möchten, ersetzen Sie die -fOption durch die -iOption.
Bill
Was wäre, wenn sich einige Dateien in diesem Verzeichnis befänden, die ich behalten wollte? Also wollte ich alle Verzeichnisse in / foo / bar / löschen, aber alle Dateien behalten, die sich dort befinden könnten.
Justingrif
2
Dies ist möglich, indem ein Pipe- stdoutBefehl (z. B. find) in den stdinanderen (z. B. rm) eingegeben wird. Seien Sie jedoch sehr vorsichtig, da er möglicherweise Dateien / Verzeichnisse löscht, die Sie nicht möchten löschen! Weitere Informationen dazu finden Sie auf den manSeiten der einzelnen Befehle. Um sicherzugehen, testen Sie solche Dinge immer in einem temporären Verzeichnis, bevor Sie die reale Sache ausprobieren.
Bill
11

Sie können die rmdirWeigerung des Befehls, nicht leere Verzeichnisse zu löschen, und die find -depthMöglichkeit nutzen, die Verzeichnisstruktur von unten nach oben zu durchlaufen:

find . -depth -exec rmdir {} \;  

(und ignorieren Sie die Fehler) oder fügen Sie 2>/dev/nullan, um sie wirklich zu ignorieren.

Die -depthOption zum findStarten der Suche am unteren Rand des Verzeichnisbaums.

rm -rflöscht alle Dateien im Verzeichnis (und seinen Unterverzeichnissen und ....) UND alle Verzeichnisse und alles.

Waltinator
quelle
8
rmdir *

Löscht alle leeren Verzeichnisse. Es wird ein Fehler für jedes nicht leere Verzeichnis und jede nicht leere Datei ausgegeben, um zu verhindern, dass diese Fehler Ihr Terminal überladen

rmdir * 2> /dev/null
Übelsuppe
quelle
Dies ist nicht für Skripte geeignet, da es mit einem Statuscode ungleich Null beendet wird, aber es funktioniert.
the_drow
@the_drow wie macht es sich ungeeignet? Übrigens kannst du auch nutzen rmdir * 2>/dev/null || true. (Der find (1) Weg ist besser für Skripte, aber aus einem anderen Grund: weil er besser ausdrückt, was Sie tun möchten.)
Alois Mahdal
Ich mache das oft bei $HOME. Mit einem bösen Grinsen.
Alois Mahdal
Denn es wird ein Fehler gemeldet, wenn einige der Verzeichnisse nicht leer sind.
the_drow
Ist dies schneller als die Find-Methode? Hat jemand die beiden verglichen?
Xerus
1
find . -type d -empty -delete -maxdepth 1

Für den Fall, dass Sie nur die direkten Unterverzeichnisse von löschen möchten foo/.

Simon Baars
quelle
0

Python-Ansatz

$ tree                                                                                                                                                                                  
.
├── empty_dir1
├── empty_dir2
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

4 directories, 4 files
$ python -c 'import os;empty=[r for r,s,f in os.walk(".") if not f and not s and r != "." ];map(lambda x: os.rmdir(x),empty)'
$ tree
.
├── subdir1
│   ├── file1.abc
│   └── file2.abc
└── subdir2
    ├── file1.abc
    └── file2.abc

Das funktioniert so:

  • Wir verwenden die os.walk()Funktion, um den Verzeichnisbaum rekursiv zu durchlaufen. Bei jeder Iteration rwird auf den aktuellen Ordner gesetzt, auf den wir zugreifen, und senthält eine Liste der darin enthaltenen Verzeichnisse rsowie feine Liste der Dateien in diesem Ordner. Wenn fund ssind natürlich leer, wissen wir, dass rdas leer ist.
  • Erstes Listenverständnis ermöglicht es uns empty, die Liste aller Verzeichnisse, die leer sind, auf der Basis der oben genannten Auswertung zu erstellen .
  • Die zweite Funktion map()wird os.rmdir()für jedes Element in der emptyListe verwendet. Das Listenverständnis könnte ebenso wie eine Alternative verwendet werden.

Als Skript wäre dies wie folgt:

#!/usr/bin/env python
import os
empty=[]
for r,s,f in os.walk("."):
    if not f and not s and r != ".":
        empty.append(r)

for i in empty:
    os.rmdir(i)
Sergiy Kolodyazhnyy
quelle
zu kompliziert für einfache Fragen :(
nurulhudamustaqim
@nurulhudamustaqim Hängt vom Standpunkt ab. Für viele Linux-Benutzer, die an Python gewöhnt sind, ist dies eigentlich sehr bescheiden :) Und abgesehen von seiner Vielfalt. Die moderne Systemadministration beschränkt sich nicht nur auf Bash /bin/shund Python ist eine elegantere Sprache als diese beiden
Sergiy Kolodyazhnyy