Wie lösche ich unter Linux alle Dateien mit Dateinamen, die Leerzeichen enthalten?

1101

Ich kann meine eigene Frage nicht löschen, stattdessen überschreiben

0
Ich habe es geschafft, alles selbst mit vi zu löschen, um die temporäre Datei zu bearbeiten, nachdem ich herausgefunden hatte, dass es auch Dateinamen gab, die Klammern enthielten - was der Shell auch nicht gefällt. vor 10 Jahren 0

2 Antworten auf die Frage

1
JdeBP

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 findBefehl einen Platzhalter übergeben, sich natürlich daran erinnern, ihn zu zitieren, und den rmBefehl 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 rmProzess 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 xargsdie 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, rmwird 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 -print0und -0sind nicht Standard, sondern GNU findund xargs, ebenso wie FreeBSD, findund xargsverstehen sie. Aber auch das ist verbesserungsfähig. Wir müssen keine zusätzlichen Prozesse generieren. Die GNU- und FreeBSD- findDateien 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 
… Also im Grunde das, was ich geschrieben habe;) Schöne Erklärung, obwohl ich empfehlen würde, die sicherste Variante an der * Oberseite * des Beitrags zu platzieren, nicht an der Unterseite. slhck vor 10 Jahren 0
Nein: was ** Ich ** am 2014-01-09 geschrieben habe und den _1-Zeichenunterschied in der Frage_ und die für die C-Shell erforderlichen geringfügigen Änderungen nachverfolgt habe. JdeBP vor 10 Jahren 0
Ich habe gerade gesehen, dass ich auch darauf geantwortet habe. Was macht es zu einem Duplikat, zumal die Antwort genau gleich ist, indem Sie nur ein Zeichen tauschen. slhck vor 10 Jahren 0
Ich wunderte mich, warum Sie es nicht als Duplikat markiert haben. Ich hielt es zurück und dachte, dass Sie Ihre Gründe haben müssen. Ich stelle fast "Doppelte Frage, also doppelte Antwort". an der Spitze aber. (-: JdeBP vor 10 Jahren 0
0
9mjb

Was ist falsch mit

rm *\ * 

oder

rm *' '* 

oder

rm *" "* 

Möglicherweise versuchen Sie 'ls', bevor Sie 'rm' ausführen, sodass Sie sicher sind, was Sie tun.

Es ist nicht rekursiv, deshalb hat das OP vielleicht `rm 'nicht verwendet. (Nicht dass es nicht geht, aber ...) slhck vor 10 Jahren 0