GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Alle Dateien außer in einem bestimmten Unterverzeichnis löschen mit Suchen?

Ich möchte rekursiv alle Dateien löschen, auf die seit einiger Zeit im Ordner a nicht zugegriffen wurde , mit Ausnahme aller Dateien im Unterordner b .

find a ( -name b -prune ) -o -type f -delete

Allerdings bekomme ich eine Fehlermeldung:

find:Die Aktion -delete schaltet automatisch -Tiefe ein, aber -prune tut
nichts, wenn -Tiefe aktiv ist. Wenn Sie trotzdem weitermachen wollen,
verwenden Sie einfach explizit die Option -depth.

Hinzufügen von -depth bewirkt alle Dateien in b enthalten sein, was nicht darf passieren.

Kennt jemand einen sicheren Weg, um dies zum Laufen zu bringen?

Akzeptierte Antwort:

Eine Möglichkeit ist die Verwendung von -exec rm statt -delete .

find a ( -name b -prune ) -o -type f -exec rm {} +

verwenden Sie alternativ -not -path statt -prune :

find a -not -path "*/b*" -type f -delete

Erklärung warum -prune kollidiert mit -delete :

finden Sie Beschwerden, wenn Sie versuchen, -delete zu verwenden mit -prune weil -delete impliziert -depth und -depth macht -prune unwirksam.

beobachten Sie das Verhalten von find mit und ohne -depth :

$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2

Es gibt keine Garantie für die Reihenfolge in einem einzelnen Verzeichnis. Aber es gibt eine Garantie, dass ein Verzeichnis vor seinem Inhalt verarbeitet wird. Beachten Sie foo/ vor jedem foo/* und foo/bar vor jedem foo/bar/* .

Dies kann mit -depth umgekehrt werden .

$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/

Beachten Sie, dass jetzt alle foo/* vor foo/ erscheinen . Dasselbe gilt für foo/bar .

weitere Erklärung:

  • -prune verhindert, dass find in ein Verzeichnis absteigt. Mit anderen Worten -prune überspringt den Inhalt des Verzeichnisses. In Ihrem Fall -name b -prune bedeutet, dass wenn find ein Verzeichnis mit dem Namen b erreicht es überspringt das Verzeichnis inklusive aller Unterverzeichnisse.
  • -depth bewirkt, dass find den Inhalt eines Verzeichnisses vor dem Verzeichnis selbst verarbeitet. Das heißt bis zu dem Zeitpunkt, an dem find den Verzeichniseintrag b verarbeitet sein Inhalt wurde bereits verarbeitet. Also -prune ist bei -depth wirkungslos in Kraft.
  • -delete impliziert -depth so kann es zuerst den Inhalt und dann das leere Verzeichnis löschen. -delete weigert sich, nicht leere Verzeichnisse zu löschen.

Erklärung der alternativen Methode:

find a -not -path "*/b*" -type f -delete

Dies kann einfacher zu merken sein oder auch nicht.

Dieser Befehl landet immer noch im Verzeichnis b und verarbeitet jede einzelne Datei darin nur für -not sie abzulehnen. Dies kann ein Leistungsproblem sein, wenn das Verzeichnis b ist riesig.

-path funktioniert anders als -name . -name stimmt nur mit dem Namen (der Datei oder des Verzeichnisses) überein, während -path entspricht dem gesamten Pfad. Beachten Sie zum Beispiel den Pfad /home/lesmana/foo/bar . -name bar stimmt überein, da der Name bar ist . -path "*/foo*" stimmt überein, weil die Zeichenfolge /foo liegt im Weg. -path hat einige Feinheiten, die Sie verstehen sollten, bevor Sie es verwenden. Lesen Sie die Manpage von find für weitere Details.

Verwandte:ado -Bedeutung finden- Dictionary Lookup!

Beachten Sie, dass dies nicht 100% narrensicher ist. Es besteht die Möglichkeit von „false positives“. Die Art und Weise, wie der Befehl oben geschrieben ist, überspringt jede Datei, die ein übergeordnetes Verzeichnis hat, dessen Name mit b beginnt (positiv). Aber es wird auch jede Datei überspringen, deren Name mit b beginnt unabhängig von der Position im Baum (falsch positiv). Dies kann behoben werden, indem ein besserer Ausdruck als "*/b*" geschrieben wird . Das bleibt dem Leser als Übung überlassen.

Ich nehme an, dass Sie a verwendet haben und b als Platzhalter und die echten Namen ähneln eher allosaurus und brachiosaurus . Wenn Sie brachiosaurus setzen anstelle von b dann wird die Menge an Fehlalarmen drastisch reduziert.

Zumindest werden die Fehlalarme nicht sein gelöscht, damit es nicht so tragisch wird. Außerdem können Sie auf Fehlalarme prüfen, indem Sie den Befehl zuerst ohne -delete ausführen (Aber denken Sie daran, die implizite -depth zu platzieren ) und untersuchen Sie die Ausgabe.

find a -not -path "*/b*" -type f -depth

Linux
  1. Centos – Alle Dateien mit einem bestimmten Namen umbenennen?

  2. Alle Dateien in einem Ordner außer den letzten (neuesten) 20 löschen?

  3. Wie lösche ich alle Dateien mit einer bestimmten Erweiterung in einem bestimmten Ordner?

  4. Wie finde ich alle Dateien mit der Endung .rb unter Linux?

  5. Alle Grafikdateien mit find auflisten?

Finden Sie verlorene Dateien mit Scalpel

So finden Sie rekursiv alle Dateien mit einer Dateigröße von Null (0) Bytes in einem Verzeichnis

Alle Dateien finden, deren Name eine Zeichenfolge enthält

Löschen Sie alle Dateien außer den neuesten 3 im Bash-Skript

Löschen Sie übereinstimmende Dateien in allen Unterverzeichnissen

Wie lösche ich alle Dateien in einem Verzeichnis außer einigen?