Wie lösche ich rekursiv Verzeichnisse mit Platzhalterzeichen?

51

Ich arbeite über SSH an einer WD My Book World Edition. Grundsätzlich möchte ich auf einer bestimmten Verzeichnisebene beginnen und alle passenden Unterverzeichnisse rekursiv entfernen .Apple*. Wie würde ich das machen?

Ich habe es versucht

rm -rf .Apple* und rm -fR .Apple*

Weder gelöschte Verzeichnisse mit diesem Namen in Unterverzeichnissen.

codedog
quelle

Antworten:

73

find ist sehr nützlich, um selektiv Aktionen für einen ganzen Baum auszuführen.

find . -type f -name ".Apple*" -delete

Hier -type fwird sichergestellt , dass es sich um eine Datei und nicht um ein Verzeichnis handelt und möglicherweise nicht genau das ist, was Sie möchten, da auch Symlinks, Sockets und andere Dinge übersprungen werden. Sie können verwenden ! -type d, was wörtlich nicht Verzeichnisse bedeutet, aber Sie können dann auch Zeichen löschen und Geräte blockieren. Ich würde vorschlagen, das -typePrädikat auf der Manpage für zu betrachten find.

Um dies ausschließlich mit einem Platzhalter zu tun, benötigen Sie erweiterte Shell-Unterstützung. Bash v4 hat die globstarOption , mit der Sie Unterverzeichnisse rekursiv abgleichen können **. zshund kshunterstützen auch dieses Muster. Damit können Sie tun rm -rf **/.Apple*. Dies ist kein POSIX-Standard und nicht sehr portabel. Daher würde ich die Verwendung in einem Skript vermeiden, aber für eine einmalige interaktive Shell-Aktion ist dies in Ordnung.

Shawn J. Goff
quelle
3
Ich kann find . -type d -name .Apple*an die Arbeit gehen - es werden alle Ordner aufgelistet. Es schlägt jedoch fehl, wenn ich -deleteam Ende hinzufüge . Es kommt gerade mit der Verwendungszusammenfassung zurück. Es läuft auf BusyBox v1.1.1. Macht das einen Unterschied?
Codedog
1
-deleteist auch nicht POSIX. **wurde zshin den frühen 90er Jahren eingeführt. Es ist jetzt (in chronologischer Reihenfolge des Auftretens) auch in ksh93, fish, bash und tcsh.
Stéphane Chazelas
1
+1 fürrm -rf **/.Apple*
Andriy Boyko
1
@codedog, wenn -deletenicht funktioniert, -exec rm -f {} +stattdessen verwenden.
Wildcard
1
Können Sie findbeim Löschen ausführlich sein? Ich nehme an, die "globstar" -Methode würde dies tun, indem sie den -vSchalter hinzufügt .
Demis
16

Ich habe Probleme beim Verwenden von findmit -deleteaufgrund des absichtlichen Verhaltens von find(dh Verweigern des Löschens, wenn der Pfad mit ./ beginnt, was in meinem Fall der Fall ist), wie in der Manpage angegeben:

 -delete

Löschen Sie gefundene Dateien und / oder Verzeichnisse. Gibt immer true zurück. Dies wird aus dem aktuellen Arbeitsverzeichnis ausgeführt, während find den Baum hinunter rekursiert. Es wird nicht versucht, einen Dateinamen mit einem "/" - Zeichen in seinem Pfadnamen relativ zu "." Zu löschen. aus Sicherheitsgründen.
Bei dieser Option wird die Verarbeitung des tiefsten Durchlaufs impliziert.
Das Folgen von Symlinks ist mit dieser Option nicht kompatibel.

Stattdessen konnte ich es einfach tun

find . -type d -name 'received_*_output' -exec rm -r {} +

In Ihrem Fall schien es die Lösung zu sein, den Glob (Sternchen, *) anzugeben, aber ich wollte meine Antwort geben, falls jemand anderes ein ähnliches Problem hatte.

HINWEIS: Zuvor lautete meine Antwort wie folgt, aber @Wildcard wies in den Kommentaren auf die Sicherheitslücken hin, die darin bestehen.

find . -type d -name 'received_*_output' | xargs rm -r
Klopfen
quelle
1
Kein guter Grund, xargshier zu verwenden . -exec rm -r {} \;oder, besser, -exec rm -r {} +funktioniert auch ohne Fehler bei Dateinamen für Sonderzeichen. Siehe Warum ist das Schleifen über Finds Ausgabe eine schlechte Übung?
Wildcard
Das ist gut zu wissen. Keine Ablehnung wert, IMO, da der Befehl immer noch die Arbeit erledigt, aber die Leistungsoptimierung wird geschätzt.
Pat
1
Wenn es nur eine Leistungsoptimierung wäre, würde ich Ihnen zustimmen, aber das ist es nicht. Es ist eine Sicherheitslücke. Sie behandeln Dateien mit Leerzeichen im Namen nicht richtig, und ein in böswilliger Absicht erstellter Dateiname führt zu Datenverlust. Siehe auch Auswirkungen auf die Sicherheit, wenn Sie vergessen, eine Variable in Bash / POSIX-Shells anzugeben . Einiges davon ist zutreffend und kann Ihnen zumindest einen Eindruck von der Art der Probleme vermitteln, über die ich spreche.
Wildcard
Versuchen Sie es mkdir -p $'blah\nDocuments\n/etc\n/home\n/received__output'in Ihrem Verzeichnis und führen Sie denselben Befehl erneut aus, wenn Sie nicht glauben, dass Daten verloren gehen können. Oder da die Frage ist über Mac OS mkdir -p $'blah\nDocuments\n/Users\n/Applications\n/received__output'. ( Warnung: Sie werden alle Ihre Dateien löschen, wenn Sie dies tun. Das ist meine Art von Punkt.)
Wildcard
0

Möglicherweise liegt an Ihrem Befehl rm / find nichts Falsches vor, aber der Benutzer, mit dem Sie angemeldet sind, verfügt tatsächlich nicht über Löschberechtigungen. Verwenden ls -lSie diese Option, um Dinge mit ihren Berechtigungen aufzulisten, und um zu identifizieren, wer Sie mit den Befehlen idund sind groups(beide sollten verfügbar sein). Wenn Sie der "falsche Benutzer" sind, müssen Sie entweder die Berechtigungen / den Besitz der Dateien ändern oder zu einem anderen Benutzer wechseln.

Froztbyte
quelle
0

Versuchen:

shopt -s dotglob           # using Bash
printf '%s\n' ./.Apple*    # test
#rm -rf ./.Apple*    
jan
quelle
1
dotglobist hier nutzlos. Auf dieser Seite finden Sie ein Beispiel für die Funktionsweise von dotglob.
Amphetamachine
-1

Einfacher Befehl:

rm `find ./ -name '.Apple*'` -rf

Viel Glück!

KimKha
quelle
4
Dies ist extrem fehleranfällig. Find has -exec key.
Anton Barkovsky