Löschen Sie Dateien mit Namen, die mit '?' in der Kommandozeile

7

Ich laufe unter Debian Stable, Cinnamon DE und habe einige Dateien, die ich mit einer Befehlszeile löschen möchte (im Moment lösche ich diese Dateien mit Nemo).

Diese .txtDateien beginnen beispielsweise mit '?' in der Schale und in Nemo dieses '?' wird durch einen Wagenrücklauf ersetzt:

$@debian: ls
ssolveIncpUL46pK  ?ssolveIncpUL46pK.txt

nemo

Ich habe es versucht:

 rm ?ss*
 rm \?ss*
 rm \ ss*
Smilia
quelle
7
Höchstwahrscheinlich handelt ?es sich nicht um ein nicht druckbares Zeichen, lsdas als dargestellt wird ?. Was ist die Ausgabe von ls | sed -n l?
Stéphane Chazelas
Was ist mit rm "?FileName"oder find . -name "\?*" -exec rm {} \; rm hat keinen Regex-Typ
Hossein Vatani
@HosseinVatani rmanalysiert ?oder nicht *, aber die Shell erweitert diese Globs vor der Ausführung rm.
Kevin Kruse
@ Kevin-Kruse Ja, ich meinte, er sollte nicht versuchen, Regex-Satz an rm zu übergeben
Hossein Vatani
1
@ StéphaneChazelas Vielleicht ls -Qwürde in Debian besser funktionieren.
Isaac

Antworten:

17

Das Zeichen ist kein Fragezeichen. Das lsDienstprogramm ersetzt nicht druckbare Zeichen durch ?. Es ist weiterhin unklar, ob das nicht druckbare Zeichen wirklich das erste Zeichen im Dateinamen ist oder ob davor ein oder mehrere Leerzeichen stehen können.

Wenn Sie beide Dateien löschen möchten, können Sie den "fehlerhaften Teil" mit *abgleichen und dann den Rest des sichtbaren Dateinamens genauer angeben:

rm -i ./*ssolve*

Dies würde zuerst das gegebene Muster auf alle passenden Dateinamen erweitern und sie dann rmentfernen. Seien Sie genauer und geben Sie einen längeren Teil des Dateinamens an, wenn Sie Dateien löschen möchten, die nicht mit dem obigen kurzen Muster übereinstimmen, z. B. mit

rm -i ./*ssolveIncpUL46pK*

Dies setzt voraus, dass Sie sich im selben Verzeichnis befinden wie die Dateien, die Sie löschen möchten.

Die -iOption, rmeine Bestätigung anzufordern, bevor etwas gelöscht wird.

Kusalananda
quelle
8
Die nächste Frage wäre: Warum passt *ssolve*es zusammen, wenn ?ss*nicht?
Stéphane Chazelas
4
@ StéphaneChazelas Da ?stimmt nicht genug mit dem "schlechten Teil" des Dateinamens überein. Es kann etwas mit Multi-Byte-Zeichen zu tun haben? Oder es kann einfach sein, dass vor dem nicht druckbaren Zeichen ein Leerzeichen steht. Mit so etwas bist du besser als ich.
Kusalananda
Wir werden es wahrscheinlich nie erfahren, wenn das OP nicht die Ausgabe von veröffentlicht ls | sed -n l.
Stéphane Chazelas
Vielleicht möchten Sie echo ./*ssolve*vor dem rm... nur für den Fall tun .
Christopher Schultz
27

Der geeignete Weg, um diese Art von Dateien zu entfernen, besteht darin, den inodeWert der Datei zu verwenden.

Verwenden Sie den folgenden Befehl, um den inodeWert abzurufen

 ls -li 

 12582925 -rw-r--r--  1 root root   646 May 23 02:19 ?ssolveIncpUL46pK.txt

Das erste Feld des Longlist-Ergebnisses ist der Inode-Wert.

Verwenden Sie dann den Befehl find, um die Datei wrt inode zu löschen.

find . -inum 12582925 -exec rm -i {} \;
Siva
quelle
Dies wäre angemessen, wenn kein Teil des Dateinamens mit einem Dateinamen-Globbing-Muster abgeglichen werden könnte und wenn die findImplementierung auf dem betreffenden System das nicht standardmäßige -inumPrädikat unterstützt (was z find. B. GNU tut).
Kusalananda
4
Das ist eigentlich unsicher. Mehr als eine Datei kann denselben Inode haben (mithilfe von Hardlinks). Anstatt also nur die Datei mit dem scheinbaren Fragezeichen zu löschen, würden Sie diese Datei und alle anderen Dateien mit derselben Inode-Nummer in diesem Verzeichnis und in allen untergeordneten Unterverzeichnissen löschen.
Flimm
@Flimm ls -liwird Ihnen sagen, ob die Datei irgendwelche festen Links hat. (Wenn die Nummer unmittelbar davor root rootist 1, gibt es keine festen Links).
Craq
1
@craq Eigentlich denke ich, dass dies unsicher sein kann, selbst wenn lsnur 1 fester Link angezeigt wird. Dies liegt daran, dass zwei separate Dateien mit separaten Dateneinträgen tatsächlich dieselbe Inode-Nummer haben können, wenn sie sich auf verschiedenen gemounteten Dateisystemen befinden, denke ich. Sie sollten wahrscheinlich die Option -xoder verwenden -xdev, um dies zu vermeiden (obwohl Sie immer noch das Problem des vorherigen Kommentars haben.)
Flimm
1
@craq Was Flimm meint, ist, dass ein Inode nauf mehreren verschiedenen gemounteten Dateisystemen für sehr unterschiedliche Dateien zugewiesen werden kann. Wenn Inode 1234 in einem Dateisystem vorhanden ist, wird nicht ausgeschlossen, dass derselbe Inode 1234 in einem anderen Dateisystem vorhanden ist.
Kusalananda
12

Es wird nicht empfohlen, a *zum Entfernen von Dateien zu verwenden. Es könnte mehr passen, als Sie möchten.

In Debian kann der lsBefehl (von GNU) die Werte der Dateien in Anführungszeichen drucken [ 1 ] :

$ ls -Q
"\nssolve"  "\n\nssolve"  "y"  "z"

Oder, noch besser, listen Sie Dateien mit zitierten Namen und Inodes auf:

$ ls -iQ
26738692 "\nssolve"  26738737 "\n\nssolve"  26738785 "y"  26738786 "z" 

Verwenden Sie dann rm mit der Inode-Nummer, um sicherzustellen, dass nur die richtigen Dateien entfernt werden:

$ find . -xdev -inum 26738737 -exec rm -i {} \;

Der Aufruf zum Suchen ist auf ein Dateisystem ( -xdev) beschränkt, um zu vermeiden, dass eine Datei in einem anderen Dateisystem mit derselben Inode-Nummer abgeglichen wird. Beachten Sie auch, dass rmdies mit der -iOption (interaktiv) aufgerufen wird , sodass in der Befehlszeile gefragt wird, ob jede Datei gelöscht werden soll.


[ 1 ] Beachten Sie, dass dies das Problem mit visuell verwirrenden Zeichen wie Kyrillisch а($ '\ U430') und Latein a($ '\ U61'), die genau gleich aussehen, aber nicht gleich sind, nicht löst. Um die Bytes, die ein Dateiname verwendet, besser sehen zu können, müssen wir einen Hex-Viewer verwenden.

$ touch а a é $'e\U301' $'\U301'e
$ ls
a  ́e  é  é  а              # what you "see" here depends on your system.

$ printf '<%s>' * | od -An -c
   <   a   >   < 314 201   e   >   <   e 314 201   >   < 303 251
   >   < 320 260   >
Isaac
quelle