Dateien mit Leerzeichen im Namen löschen

10

Ich versuche, alle Dateien mit einem Leerzeichen in ihren Namen zu löschen. Ich benutze folgenden Befehl. Aber es gibt mir einen Fehler

Befehl : ls | egrep '. ' | xargs rm

Wenn ich hier nur den ls | egrep '. 'Befehl verwende, erhalte ich den gesamten Dateinamen mit Leerzeichen in den Dateinamen. Wenn ich jedoch versuche, die Ausgabe an rm zu übergeben, werden alle Leerzeichen (führende oder nachfolgende) gelöscht. Mein Befehl wird also nicht richtig ausgeführt.

Gibt es Hinweise, wie die Datei gelöscht werden kann, deren Name mindestens ein Leerzeichen enthält?

Anuj
quelle

Antworten:

29

Sie können Standard-Globbing auf dem verwenden rm Befehl verwenden:

rm -- *\ *

Dadurch werden alle Dateien gelöscht, deren Name ein Leerzeichen enthält. Das Leerzeichen wird maskiert, sodass die Shell es nicht als Trennzeichen interpretiert. Durch --das Hinzufügen werden Probleme mit Dateinamen vermieden, die mit Bindestrichen beginnen (sie werden von nicht als Argumente interpretiert rm).

Wenn Sie jede Datei vor dem Löschen bestätigen möchten, fügen Sie die folgende -iOption hinzu:

rm -i -- *\ *
Stephen Kitt
quelle
4
Sie werden dies definitiv durch eine echoerste führen wollen, um sich vor Tippfehlern zu schützen. Fügen Sie echovorne hinzu, und es werden alle Dateien ausgedruckt, die entfernt werden sollen.
Riking
1
Anuj, der Grund, warum dies die meisten positiven Stimmen hat, ist, dass findman das Huhn manchmal nicht mit einem Maschinengewehr töten muss, obwohl es mächtig ist. UNIX-Administratoren würden im Allgemeinen nicht findauf (zum Beispiel) "alle Dateien entfernen, die mit dem Buchstaben A beginnen" zurückgreifen ... man würde einfach rm A*. Ebenso kann rm die Arbeit erledigen, um Dateien zu entfernen, die Leerzeichen enthalten. Mit anderen Worten, lassen Sie sich nicht täuschen, denn der Raum ist unsichtbar und wird von der Shell speziell behandelt. Entkomme einfach, wie Stephen Kitt es getan hat, und du kannst es dir wie jeden anderen Charakter vorstellen.
Mike S
14

Ich würde das Parsen vermeiden ls Ausgabe zu

Warum nicht :

find . -type f -name '* *' -delete

Kein Problem mit rm :-).

Dies ist zwar rekursiv und löscht alle Dateien mit Speicherplatz im aktuellen Verzeichnis und in verschachtelten Verzeichnissen, wie in den Kommentaren erwähnt.

Sonnenwende
quelle
4
(1) Sie können -name '* *'anstelle des regulären Ausdrucks verwenden; und (2) Sie können -print0 | xargs -0 rm -i@ StephenKitts Anliegen ansprechen.
Kevin
1
Keine Notwendigkeit für xargs. Verwenden Sie einfach-exec rm -i '{}' +
R .. GitHub STOP HELPING ICE
1
@Mhmd Es hat mehr Fallstricke als eine 8-Bit-Spielekonsole. mywiki.wooledge.org/ParsingLs
Daenyth
1
Wenn Sie Unterverzeichnisse vermeiden möchten, verwenden Sie find . -maxdepth 1 -name '* *' -delete.
Mikkel
1
@ BenjaminW. Fest ?
SolsTiCe
6

Schauen Sie sich diesen Angenommenen Namen "seltsame Datei" an

Lösung eins

rm strange\ file

Lösung zwei

rm "strange file"

Lösung drei

ls -i "strange file"

Sie sehen dann die Inode

find . -inum "numberoofinode" -exec rm {} \;

Bei sehr seltsamen Dateinamen wie

!-filename or --filename

verwenden

rm ./'!-filename'
Elbarna
quelle
4

Von man xargs

xargs liest Elemente aus der Standardeingabe, die durch Leerzeichen (die durch doppelte oder einfache Anführungszeichen oder einen Backslash geschützt werden können) oder Zeilenumbrüche begrenzt sind, und führt den Befehl (Standard ist / bin / echo) ein- oder mehrmals mit den folgenden Anfangsargumenten aus durch Elemente, die aus der Standardeingabe gelesen wurden. Leerzeilen am Standardeingang werden ignoriert.

Wir können Ihren anfänglichen Befehl (meistens) korrigieren, indem wir das xargs-Trennzeichen in eine neue Zeile ändern:

ls | egrep '. ' | xargs -d '\n' rm (Tu das nicht ... lies weiter)

Was aber, wenn der Dateiname eine neue Zeile enthält?

touch "filename with blanks and newline"

Da Unix-Dateinamen Leerzeichen und Zeilenumbrüche enthalten können , ist dieses Standardverhalten häufig problematisch. Dateinamen, die Leerzeichen und / oder Zeilenumbrüche enthalten, werden von xargs falsch verarbeitet. In diesen Situationen ist es besser, die Option -0 zu verwenden , um solche Probleme zu vermeiden.

ls ist wirklich ein Werkzeug für den direkten Verbrauch durch einen Menschen , stattdessen müssen wir den findBefehl verwenden, der die Dateinamen durch ein Nullzeichen ( -print0) trennen kann . Wir müssen grep auch anweisen, Nullzeichen zu verwenden, um input ( -z) und output ( -Z) zu trennen . Schließlich weisen wir xargs an, auch Nullzeichen ( -0) zu verwenden.

find . -type f -print0 | egrep '. ' -z -Z | xargs -0 rm

anjsimmo
quelle
1

Sie können verwenden:

find . -name '* *' -delete
Max ZHUANG
quelle
rm - * \ * scheint besser
Max ZHUANG
Dies wurde auch durch Kevins Kommentar zur Antwort von solsTiCe abgedeckt .
G-Man sagt 'Reinstate Monica'
-1

Um dies zu tun, benötigen Sie die -ZOption grep und die -0Option xargs. Aber ich würde es nicht so machen (ls ist nicht das richtige Werkzeug für den Job, es gibt viele Probleme, den Computer dazu zu bringen, seine Ausgabe zu lesen).

Weitere Antworten finden Sie auf andere Weise.


Ebenfalls

ls | … ist äquivalent zu ls -d * undecho * | …

Alle haben Probleme. Verwenden Sie daher nicht lsso, sondern eine Lösung aus einer anderen Antwort.

Strg-Alt-Delor
quelle
Auch ls *wenn Pipes ausgegeben werden, werden die Dateinamen durch neue Zeilen getrennt. echo(zumindest einige echoImplementierungen) erweitert Backslash-Sequenzen. grep -Zdient zum Schreiben von Dateinamen, die bei Verwendung NUL-getrennt sind -l, hilft hier nicht weiter. Wenn Sie das gemeint haben -z, hilft das auch nicht, da die meisten lsImplementierungen keine Option zum Ausgeben von NUL-getrennten Dateinamen haben. Man könnte aber so etwas machen printf '%s\0' * | grep -z ' ' | xargs -r0 rm -f.
Stéphane Chazelas
1
@Kusalananda Ich glaube, ich habe es behoben.
Strg-Alt-Delor