Wie entferne ich eine Datei in Linux, deren Name NUR wie ein Bindestrich aussieht, wie in "-"

33

ich habe es versucht

rm -- -
rm "-"
rm "\-"
rm \-

Hat Perl einen Schuss gegeben

~$ perl -e '$junk = glob("-"); chomp $junk; print "$junk\n"; `rm $junk`;'
-
rm: cannot remove `-': No such file or directory

...und...

~$ perl -e '$junk = glob("-"); chomp $junk; print "$junk\n"; `mv $junk newfile.garbage`;'
-
mv: cannot stat `-': No such file or directory

Jede Unterstützung wäre sehr dankbar, weise Leute.

jgrundstad
quelle
Wie ist es aus Neugier dorthin gekommen?
Petey B
2
Es war das Ergebnis eines schlecht konstruierten wget: "wget ​​-q -O - someserver.org/s/ip "
53
Erinnert mich an die Zeit, als ein Kollege eine Datei mit dem Namen * erstellt hat. Diese Geschichte endete nicht gut.
David Heffernan
Welche rmVersion verwenden Sie ( rm --version)? rm -funktioniert gut mit GNU Coreutils 8.5.
Lekensteyn
2
Eine andere Variante:rm ./-
ein CVn

Antworten:

60

Dies wurde früher in den Usenet-FAQs für Unix gepostet - ich sehe es in den GNU Core Utility-FAQs . Es gab mindestens fünf verschiedene Methoden, aber das funktioniert gut:

$ rm ./-

Wenn ein Dateiname untypisierbare Zeichen enthält, verwenden Sie:

$ rm -i *

Das -iFlag fragt nach einer Bestätigung für jede Datei, ob sie entfernt werden soll oder nicht.

wallyk
quelle
1
Oder rm -i - ' - ', wenn Sie nach Dateien suchen, die einen Bindestrich und möglicherweise Leerzeichen oder was auch immer enthalten.
Hans-Peter Störr
1
rm -i * hat auch für mich gearbeitet. Vielen Dank, Wallyk!
Jgrundstad
39

Das Entfernen einer Datei, deren Name mit "" beginnt, -ist eine häufig gestellte Frage, aber es sieht so aus, als hätten Sie ein anderes Problem.

Von den Lösungen, die Sie in der Frage erwähnt haben:

rm -- -

Das sollte funktionieren.

rm "-"

Das ist nicht anders als rm -. Die Anführungszeichen werden von der Shell entfernt, und der rmBefehl sieht nur den einzelnen Bindestrich als Argument. Anführungszeichen sind nützlich, um Shell-Metazeichen zu maskieren. Der Bindestrich ist speziell für rm, nicht für die Shell.

rm "\-"

Die Anführungszeichen werden vor dem umgekehrten Schrägstrich angezeigt. Dadurch wird versucht, eine Datei zu entfernen, deren Name aus zwei Zeichen besteht, einem umgekehrten Schrägstrich und einem Bindestrich.

rm \-

Das ist genauso rm "-", äquivalent zu rm -.

Da es zumindest mit dem GNU geschieht, coreutils Version rm, rm -tatsächlich entfernt (oder versucht zu entfernen) einen Dateinamen besteht aus nur einem Bindestrich , das. Wenn Ihre Datei diesen Namen hätte, wäre sie inzwischen verschwunden. Ich komme zu dem Schluss, dass Ihre Datei einen Namen hat, der nur wie ein Bindestrich aussieht .

ls | cat -A

sollte eine Vorstellung davon geben, wie es wirklich heißt.

Hier ist ein Perl-Skript, das ich gerade zusammengestellt habe und das Sie auffordert, jede Datei im aktuellen Verzeichnis zu löschen. Wird ohne Garantie angeboten, habe es aber kurz getestet.

#!/usr/bin/perl

use strict;
use warnings;

$| = 1;

opendir my $DIR, '.' or die ".: $!\n";
my @files = sort grep { -f $_ } readdir $DIR;
closedir $DIR;

foreach my $file (@files) {
    print "Remove $file? ";
    my $answer = scalar <>;
    if ($answer =~ /^[Yy]/) {
        unlink $file or warn "$file: $!\n";
    }
    elsif ($answer =~ /^[Qq]/) {
        exit 0;
    }
}

BEARBEITEN : Eine weniger aufwändige Lösung: Wenn der Name der Datei nur ein Zeichen ist, rm ?sollte er entfernt werden (zusammen mit allen anderen derartigen Dateien).

Keith Thompson
quelle
13
M-bM-^@M-^Sist eine Wiedergabe der 3-Byte-UTF-8-Darstellung des Unicode-Zeichens "EN DASH", 0x2013. Ich frage mich, ob Sie es versehentlich von einer Webseite kopiert und eingefügt haben.
Keith Thompson
7
hat rm -i *nicht funktioniert? Scheint, als würde es dasselbe tun wie das Perl-Skript.
user606723
2
Ich vermute, dass es von der Webseite stammt, auf die ich den wget zeigte. Auf jeden Fall nochmals vielen Dank für die gründliche Lösung! Pass auf.
Jgrundstad
5
perl -e 'unlink grep {print "$ _ entfernen?"; <STDIN> = ~ / y / i} glob "*" '
Randal Schwartz
6
@RandalSchwartz: Beeindruckend knapp (und mein Gehirn tut ein bisschen weh) - aber ich möchte /^y/ilieber als /y/i. Schließlich könnte ein russischer Benutzer "Nyet" eingeben.
Keith Thompson
19

Wenn Sie etwas sichereres wollen ...

Versuchen Sie es mit einer Kombination aus ls und find (dies funktioniert für jede Datei, zu deren Entfernen Sie berechtigt sind).

Der Parameter '-i' gibt Ihnen die Inode-Nummer für jeden Verzeichniseintrag ls -li an

27 ----------  1 owner  group       3981 Oct 11 04:42 ?????

Sobald Sie die Inode-Nummer haben ...

find . -inum **27** -exec rm -i {} \;
Sam
quelle
2
+1, da dies eine gute allgemeine Antwort auf diese Probleme ist. Übrigens gibt es keine Notwendigkeit, -exec rm in den neuesten Entdeckungen zu verwenden, verwenden Sie einfach -delete
Sirex
2
@ Sirex - Ich denke, es -exec rm -i {}geht -idarum, zum Entfernen aufzufordern . Ich schaue man findund sehe keinen Weg, das zu tun.
Stephen P
ach ja, in diesem fall. war eher ein tipp.
Sirex
13

Probieren Sie rm ./-es aus.

Das -ist ein Flag, um ein Flag-Argument zu starten. Wenn Sie das Argument mit etwas anderem als einem beginnen -, wird in diesem Fall /davon ausgegangen, dass es sich um den Dateinamen handelt. Welches ist, was Sie wünschen.

Und da fileund ./filedie gleiche Datei ist, wird die Datei mit dem Namen Ziel -über ./-.

Petey B
quelle
8
Anstatt 30 Zeichen einzugeben, wäre es vielleicht sinnvoller gewesen zu erklären, warum das / hilft, richtig zu analysieren
Ivo Flipse
@gcb Danke für die vorgeschlagene Bearbeitung. Ich habe dem Code-Markup hinzugefügt, damit es leichter zu lesen ist.
Slhck
7

Nicht so geeky wie die meisten anderen Antworten, aber ich würde eine Instanz von mcMidnight Commander starten und einfach die Datei auswählen und löschen.

johanvdw
quelle
+1 für geschicktes Ausweichen - und das, ohne auf ein GUI-Programm zurückzugreifen.
sleske
7

Versuchen:

$ ls -b

um zu sehen, ob der Dateiname nicht druckbare Zeichen enthält.

Noel Yap
quelle
Warum die Gegenstimme? In Anbetracht des Nachfassens klingt dies nach einem sehr guten Vorschlag.
Ilmari Karonen
6

Nicht, dass es notwendig sein sollte, hier Perl zu verwenden, aber das sollte funktionieren:

perl -e 'unlink "-"'

oder um zu sehen, was ein Fehler mit dem oben genannten sein könnte:

perl -e 'unlink "-" or die "Err: $!"'
runrig
quelle
Diese Methode hat den Vorteil, dass es keine Sonderzeichen gibt, über die Sie sich Gedanken machen müssen (abgesehen von Problemen beim Zitieren von Zeichenfolgen).
Kevin Reid
3

Ich hatte Glück, GNOMEs Nautilus zu verwenden, um falsch benannte Dateien zu entfernen. Betreiben Sie einen X-Server? Ich bin sicher, dass andere Dateibrowser auch funktionieren würden.

Joel Berger
quelle
3

Ob

rm -- -

hat nicht funktioniert, der Dateiname ist nicht "nur ein Bindestrich". Wenn keine anderen Dateien einen Bindestrich enthalten, können Sie es versuchen

perl -E'for (@_) { if (/-/) { unlink($_) or die $! } }' -- *
Ikegami
quelle
1

Bisher bekomme ich für jede bisher gepostete Methode ein "No such file or directory":

rm ./-
rm -- -
mv "-" test.txt
rm -rf '-' <-- this gives no error, but doesn't work
perl -e 'unlink "-";'  <--also no error, doesn't work.

Es scheint, dass ich rm Version 7.4 habe. Ich werde versuchen, diese Vorschläge zu aktualisieren und erneut zu versuchen. Vielen Dank an alle für die Hilfe.

jgrundstad
quelle
1
Ich vermute, dass es keine solche Datei oder Verzeichnis gibt, und vielleicht enthält der Dateiname auch einige unsichtbare Zeichen. (und du könntest ungefähr die gleiche Fehlermeldung in Perl mit 'unlink "-" oder die "Err: $!"' bekommen). Versuchen Sie "ls -b", um den tatsächlichen Dateinamen zu ermitteln.
Runrig
1

Ich verwende sehr gerne den diredModus in Emacs für diese Art von Dingen - öffne einfach das Verzeichnis in Emacs. Sie können Dateien einfach auswählen und zum Löschen markieren.

Ein anderes Plakat schlug die Verwendung des Mitternachtskommandanten vor; Dies ist so ziemlich die gleiche Idee, aber wenn Sie bereits ein Emacs-Benutzer sind, ist es vielleicht bequemer.

Ernest Friedman-Hill
quelle
0

Sollte rm -f '-'für mich in cygwin arbeiten können

Übrigens rm -scheint auch Red Hat zu funktionieren.

Lucas
quelle
in Ubuntu: ~ / jj $ rm -rf '-' ~ / jj $ ls -
rm -funktioniert auch bei mir
Uzsolt
1
Warum -r? Eine rekursive Löschung anzufordern, wenn Sie sie nicht benötigen, ist im Falle von Rechtschreibfehlern immer gefährlich.
Hans-Peter Störr
@ hstoerr, guter Punkt. nur habbit. Hände tippen schneller als Gehirn. Antwort jetzt bearbeiten, danke.
Lucas