Keine Notwendigkeit für Pipes, xargs, exec oder irgendetwas:
find . -name .svn -delete
Bearbeiten: Nur ein Scherz, offensichtlich -delete
ruft unlinkat()
auf unter der Haube, also verhält es sich wie unlink
oder rmdir
und weigert sich, mit Verzeichnissen zu arbeiten, die Dateien enthalten.
Was Sie geschrieben haben, sendet eine Liste von durch Zeilenumbrüche getrennten Dateinamen (und Pfaden) an rm
, aber rm weiß nicht, was er mit dieser Eingabe anfangen soll. Es erwartet nur Kommandozeilenparameter.
xargs
Nimmt Eingaben entgegen, die normalerweise durch Zeilenumbrüche getrennt sind, und fügt sie in die Befehlszeile ein, sodass das Hinzufügen von xargs dazu führt, dass das, was Sie hatten, funktioniert:
find . -name .svn | xargs rm -fr
xargs
ist intelligent genug, dass nur so viele Argumente an rm
übergeben werden wie es annehmen kann. Wenn Sie also eine Million Dateien hätten, könnte es rm
ausführen 1.000.000/65.000 Mal (wenn Ihre Shell 65.002 Argumente auf der Befehlszeile akzeptieren könnte {65.000 Dateien + 1 für rm + 1 für -fr}).
Wie Personen geschickt darauf hingewiesen haben, funktionieren auch die folgenden:
find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf
Die ersten beiden -exec
Formen rufen beide rm
auf für jeden zu löschenden Ordner, also wenn Sie 1.000.000 Ordner hätten, rm
1.000.000 Mal aufgerufen werden. Dies ist sicherlich weniger als ideal. Neuere Implementierungen von rm
können Sie den Befehl mit einem +
abschließen was darauf hinweist, dass rm
akzeptiert so viele Argumente wie möglich:
find . -name .svn -exec rm -rf {} +
Die letzte find/xargs-Version verwendet print0, wodurch find eine Ausgabe generiert, die \0
verwendet als Terminator und nicht als Zeilenumbruch. Da POSIX-Systeme alle Zeichen außer \0
zulassen im Dateinamen ist dies wirklich der sicherste Weg, um sicherzustellen, dass die Argumente korrekt an rm
übergeben werden oder die ausgeführte Anwendung.
Außerdem gibt es einen -execdir
das wird rm
ausführen aus dem Verzeichnis, in dem die Datei gefunden wurde, und nicht aus dem Basisverzeichnis und einem -depth
das wird zuerst die Tiefe starten.
Versuchen Sie Folgendes:
find . -name .svn -exec rm -rf '{}' \;
Bevor ich einen solchen Befehl ausführe, möchte ich oft zuerst diesen ausführen:
find . -name .svn -exec ls '{}' \;