Come rimuovo un file in Linux il cui nome sembra SOLO un trattino, come in "-"


33

ho provato

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

Ho dato a Perl un colpo

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

...e...

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

Qualsiasi aiuto sarebbe molto apprezzato, gente saggia.


Per curiosità, come ci è arrivato?
Petey B,

2
Era il risultato di un wget mal costruito: "wget ​​-q -O - someserver.org/s/ip "

53
Mi ricorda quando un collega ha creato un file chiamato *. Questa storia non è finita bene.
David Heffernan,

Quale rmversione stai usando ( rm --version)? rm -funziona bene con coreutils GNU 8.5.
Lekensteyn,

2
Un'altra variante:rm ./-
un CVn il

Risposte:


60

Questo era pubblicato nelle FAQ di Usenet per Unix — Vedo che è nelle FAQ di GNU Core Utility . C'erano almeno cinque metodi diversi, ma questo funziona bene:

$ rm ./-

Se un nome file contiene caratteri non tipizzabili, utilizzare:

$ rm -i *

Il -iflag chiede conferma per ogni file se deve essere rimosso o meno.


1
Oppure rm -i - ' - ' se stai cercando file contenenti un trattino e forse alcuni spazi o altro.
Hans-Peter Störr,

1
rm -i * ha funzionato anche per me. Grazie Wallyk!
jgrundstad,

39

La rimozione di un file il cui nome inizia con -una FAQ, ma sembra che tu abbia un problema diverso.

Delle soluzioni che hai menzionato nella domanda:

rm -- -

Dovrebbe funzionare.

rm "-"

Non è diverso da rm -. Le virgolette sono rimosse dalla shell e il rmcomando vede il singolo trattino come argomento. Le virgolette sono utili per sfuggire ai metacaratteri della shell; il trattino è speciale rm, non per la shell.

rm "\-"

Le virgolette sfuggono alla barra rovesciata, quindi questo tenta di rimuovere un file il cui nome è composto da due caratteri, una barra rovesciata e un trattino.

rm \-

Questo è proprio come rm "-", equivalente a rm -.

A quanto pare, almeno con la versione GNU coreutils di rm, rm -effettivamente rimuove (o tenta di rimuovere) un file il cui nome è costituito solo da un trattino. Se il tuo file avesse quel nome, ora sarebbe andato. Concludo che il tuo file ha un nome che sembra solo un trattino.

ls | cat -A

dovrebbe dare un'idea di come si chiama davvero.

Ecco uno script Perl che ho appena messo insieme che ti chiederà ogni file nella directory corrente e ti chiederà se rimuoverlo. Offerto senza garanzia, ma l'ho testato brevemente.

#!/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;
    }
}

EDIT : una soluzione meno elaborata: se il nome del file è solo un carattere, rm ?dovrebbe rimuoverlo (insieme a qualsiasi altro file simile).


13
M-bM-^@M-^Sè una rappresentazione della rappresentazione UTF-8 a 3 byte del carattere Unicode "EN DASH", 0x2013. Mi chiedo se l'hai accidentalmente copiato e incollato da una pagina web.
Keith Thompson,

7
non rm -i *ha funzionato? Sembra che farebbe la stessa cosa dello script perl.
user606723,

2
Immagino che sia nato dalla pagina web a cui ho indicato la wget. In ogni caso, grazie ancora per la soluzione completa! stai attento.
jgrundstad,

5
perl -e 'unlink grep {print "rimuovi $ _?"; <STDIN> = ~ / y / i} glob "*" '
Randal Schwartz,

6
@RandalSchwartz: straordinariamente conciso (e mi fa un po 'male al cervello) - ma vorrei /^y/ipiuttosto che /y/i. Dopotutto, un utente russo potrebbe digitare "Nyet".
Keith Thompson,

19

Se vuoi qualcosa di più sicuro ...

Prova a utilizzare una combinazione di ls e trova (funziona per qualsiasi file che hai l'autorizzazione a rimuovere)

Il parametro '-i' ti darà il numero di inode per ogni voce di directory ls -li

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

Una volta che hai il numero di inode ...

find . -inum **27** -exec rm -i {} \;

2
+1 poiché questa è un'ottima risposta generale per questi problemi. A proposito, non c'è bisogno di usare -exec rm negli ultimi ritrovamenti, basta usare -delete
Sirex

2
@Sirex - Penso che il punto -exec rm -i {}sia la -irichiesta di rimozione. Sto guardando man finde non vedo alcun modo per farlo.
Stephen P

oh sì, in questo caso. era più di un suggerimento.
Sirex

13

Dare rm ./-una prova.

Il -è una bandiera di avviare un argomento flag. Se si avvia l'argomento con tutt'altro che a -, in questo caso /, assumerà che sia il nome del file. Qual è quello che desideri.

E da allora file e ./filesono lo stesso file, sarà indirizzato al file denominato -via ./-.


8
Invece di digitare 30 caratteri, forse sarebbe stato più utile spiegare perché il / aiuta ad analizzare correttamente
Ivo Flipse,

@gcb Grazie per la modifica proposta. Ho aggiunto il markup del codice a quello, quindi sarebbe più facile da leggere.
Slhck,

7

Non è geniale come la maggior parte delle altre risposte, ma accenderei un'istanza di mc, comandante di mezzanotte, e selezionerei ed eliminerei il file.


+1 per abilmente aggirare il problema, e senza nemmeno ricorrere a un programma di interfaccia grafica.
sleske,


6

Non che dovrebbe essere necessario usare perl qui, ma questo dovrebbe funzionare:

perl -e 'unlink "-"'

o per vedere quale potrebbe essere qualsiasi errore con quanto sopra:

perl -e 'unlink "-" or die "Err: $!"'

Questo metodo ha il vantaggio che non ci sono caratteri speciali di cui preoccuparsi (oltre ai problemi di quotatura di stringhe).
Kevin Reid,

3

Ho avuto fortuna ad usare il Nautilus di GNOME per rimuovere file con nomi errati. Stai eseguendo un X-server? Sono sicuro che anche altri browser di file funzionerebbero.


3

Se

rm -- -

non ha funzionato, il nome del file non è "solo un trattino". Se nessun altro file contiene un trattino, puoi provare

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

1

Finora ricevo un "Nessun file o directory" per ogni metodo pubblicato finora:

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

Sembra che abbia rm versione 7.4. Proverò ad aggiornare e ritentare questi suggerimenti. Grazie a tutti per l'aiuto.


1
Immagino che non ci sia un tale file o directory, e forse il nome del file contiene anche alcuni caratteri invisibili. (e potresti ottenere lo stesso messaggio di errore in perl con 'unlink "-" o die "Err: $!"'). Prova "ls -b" per vedere qual è il vero nome del file.
Runrig,

1

Mi piace molto usare la diredmodalità in emacs per questo tipo di cose - basta "aprire" la directory in emacs. È possibile selezionare facilmente i file e contrassegnarli per l'eliminazione.

Un altro poster suggeriva di usare il comandante di mezzanotte; questa è praticamente la stessa idea, ma se sei già un utente emacs è forse più conveniente.


0

Dovrei essere in grado di rm -f '-'lavorare per me su Cygwin

Del rm -resto , sembra funzionare anche su Red Hat.


in Ubuntu: ~ / jj $ rm -rf '-' ~ / jj $ ls -

rm -funziona anche per me.
uzsolt,

1
Perché -r? Richiedere una cancellazione ricorsiva se non è necessario è sempre pericoloso in caso di errori di selezione.
Hans-Peter Störr,

@hstoerr, buon punto. solo habbit. le mani digitano più velocemente del cervello. modifica risposta ora, grazie.
Lucas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.