Wie entferne ich rekursiv Unterverzeichnisse und Dateien, aber nicht das erste übergeordnete Verzeichnis?

10

Ich kann Folgendes verwenden, um das Zielverzeichnis und rekursiv alle seine Unterverzeichnisse und Inhalte zu entfernen.

find '/target/directory/' -type d -name '*' -print0 | xargs -0 rm -rf

Ich möchte jedoch nicht, dass das Zielverzeichnis entfernt wird. Wie kann ich nur die Dateien im Ziel, die Unterverzeichnisse und deren Inhalt entfernen?

Michael Prescott
quelle

Antworten:

11

Die vorherige Antwort ist fast richtig. Sie sollten die Shell-Glob-Zeichen jedoch nicht in Anführungszeichen setzen, wenn Sie möchten, dass sie funktionieren. Dies ist also der Befehl, den Sie suchen:

rm -rf "/target/directory with spaces/"*

Beachten Sie, dass das * außerhalb der Anführungszeichen steht. Dieses Formular würde auch funktionieren:

rm -rf /target/directory\ with\ spaces/*

Wenn Sie die *Anführungszeichen wie oben angegeben haben, wird nur versucht, die einzelne Datei zu entfernen, die *im Zielverzeichnis buchstäblich benannt ist.

Pioto
quelle
1
Dies funktioniert nicht mit versteckten Dateien und Ordnern. Ich musste es noch einmal mit einem tun
The Unfun Cat
7

Drei weitere Optionen.

  1. Verwenden Sie findmit -mindepth 1und -delete:

    −Mindepth Levels Wenden
    Sie keine Tests oder Aktionen auf Levels an, die niedriger sind als Levels (eine nicht negative ganze Zahl).
    −mindepth 1 bedeutet, dass alle Dateien außer den Befehlszeilenargumenten verarbeitet werden.

    -Löschen
    Dateien löschen ; true, wenn das Entfernen erfolgreich war. Wenn das Entfernen fehlgeschlagen ist, wird eine Fehlermeldung ausgegeben. Wenn das Löschen fehlschlägt, ist der Exit-Status von find ungleich Null (wenn es schließlich beendet wird). Bei Verwendung von -delete wird die Option -depth automatisch aktiviert.
    Testen Sie die Option -depth sorgfältig, bevor Sie diese Option verwenden.

    # optimal?
    # -xdev      don't follow links to other filesystems
    find '/target/dir with spaces/' -xdev -mindepth 1 -delete
    
    # Sergey's version
    # -xdev      don't follow links to other filesystems
    # -depth    process depth-first not breadth-first
    find '/target/dir with spaces/' -xdev -depth -mindepth1 -exec rm -rf {} \;
    



2. Verwenden Sie find, aber mit Dateien, keine Verzeichnisse. Dies vermeidet die Notwendigkeit rm -rf:

    # delete all the files;
    find '/target/dir with spaces/' -type f -exec rm {} \;

    # then get all the dirs but parent
    find '/target/dir with spaces/' -mindepth 1 -depth -type d -exec rmdir {} \;

    # near-equivalent, slightly easier for new users to remember
    find '/target/dir with spaces/' -type f -print0 | xargs -0 rm
    find '/target/dir with spaces/' -mindepth 1 -depth -type d -print0 | xargs -0 rmdir



3. Entfernen Sie das übergeordnete Verzeichnis, erstellen Sie es jedoch erneut. Sie können eine Bash-Funktion erstellen, um dies mit einem Befehl zu tun. Hier ist ein einfacher Einzeiler:

    rm -rf '/target/dir with spaces' ; mkdir '/target/dir with spaces'
Quacksalber
quelle
2

Wie wäre es mit

rm -rf /target/directory\ path/*

Wenn es Dateien gibt, die mit beginnen. im Zielverzeichnis.

rm -rf "/target/directory path/*" "/target/directory path/.??*"

Diese Sekunde passt zu allem, was mit einem. Beginnt, außer. und .. Es wird bei Namen wie .a scheitern, aber das ist nicht sehr verbreitet. Es könnte bei Bedarf angepasst werden, um alle Fälle abzudecken.

KeithB
quelle
Ich habe beide ausprobiert und sie arbeiten nicht für mich. Vielleicht liegt es daran, dass mein Zielverzeichnispfad Leerzeichen enthält? rm -rf '/ target / directory path / *' Es wird kein Fehler ausgegeben, aber die Unterverzeichnisse bleiben bestehen.
Michael Prescott
Sie müssen die Leerzeichen entweder mit einem Backslash (\) vor dem Leerzeichen oder durch Einschließen des gesamten Verzeichnisnamens in Anführungszeichen (")
umgehen
Danke, ich habe versucht, das wie in meinem vorherigen Kommentar gezeigt und immer noch nicht zu gehen. (Ich benutze OS X, ist das wichtig?)
Michael Prescott
OS X sollte gut funktionieren, das ist, was ich benutze. Stellen Sie sicher, dass Sie weder Backslash noch Anführungszeichen verwenden. Nur der eine oder andere.
KeithB
Ja, nur unter Verwendung der Anführungszeichen. Wenn ich das * entferne und nur rm -rf "/ target / directory path /" verwende, wird das Verzeichnis "directory path" zusammen mit den Unterverzeichnissen "directory path" entfernt. Wenn ich das rm -rf "/ target / directory path / *" verwende, passiert nichts.
Michael Prescott
2
find /target/directory/ -xdev -depth -mindepth 1 -exec rm -Rf {} \;
Sergey
quelle