Okay, lass uns das schrittweise machen.
Und nehmen wir an, Sie wollen wirklich auch in Unterverzeichnisse schauen, auch wenn dies nur in Ihrer Frage impliziert ist.
Als ersten Durchlauf ist dies nur eine einfache Übung, indem Sie dem find
Befehl einen Platzhalter übergeben, sich natürlich daran erinnern, ihn zu zitieren, und den rm
Befehl für jede gefundene Datei ausführen :
find $BASE_DIR/ -name '* *' -exec rm {} \;
Aber das ist natürlich furchtbar ineffizient. Es wird ein vollständiger rm
Prozess für jede einzelne Datei gestartet. Wir könnten zwar einen kurzen Umweg machen \+
, denn hier werden wir nicht enden. Nehmen wir also den kürzeren Weg und bringen Sie xargs
die Dateinamen in Gruppen zusammen:
find $BASE_DIR/ -name '* *' -print | xargs rm
Das hat aber zwei Sicherheitslücken. Wenn ein gefundener Dateiname mit einem Minuszeichen beginnt, rm
wird er zuerst als Befehlszeilenoption und nicht als Dateiname behandelt und ein Fehler generiert. (Die -exec rm {}
Version hat auch dieses Problem.) Zweitens werden Dateinamen, die Leerzeichen enthalten, nicht ordnungsgemäß von behandelt xargs
, wie Sie bemerkt haben. Eine weitere Wiederholung ist es, dies etwas kugelsicherer zu machen:
find $BASE_DIR/ -name '* *' -print0 | xargs -0 rm --
Und natürlich gibt es die interaktiven Funktionen rm
, die Sie wahrscheinlich nicht möchten:
find $BASE_DIR/ -name '* *' -print0 | xargs -0 rm -f --
Die Optionen -print0
und -0
sind nicht Standard, sondern GNU find
und xargs
, ebenso wie FreeBSD, find
und xargs
verstehen sie. Aber auch das ist verbesserungsfähig. Wir müssen keine zusätzlichen Prozesse generieren. Die GNU- und FreeBSD- find
Dateien können den unlink(2)
Systemaufruf direkt aufrufen:
find $BASE_DIR/ -name '* *' -delete
Denken Sie als letzte vorbeugende Maßnahme daran, dass Sie unter bestimmten Umständen nicht mehr tun, als Sie beabsichtigten. Denken Sie daran, dass das Dateisystem mehr als nur reguläre Dateien enthalten kann:
find $BASE_DIR/ -name '* *' -type f -delete