Jak usunąć plik w systemie Linux, którego nazwa wygląda na TYLKO łącznik, jak w „-”

33

próbowałem

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

Dał Perlowi szansę

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

...i...

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

Każda pomoc będzie mile widziana, mądrzy ludzie.

jgrundstad
źródło
Z ciekawości, jak się tam dostał?
Petey B
2
Był to wynik źle skonstruowanego wgeta: „wget -q -O - someserver.org/s/ip
53
Przypomina mi, kiedy kolega utworzył plik o nazwie *. Ta historia nie skończyła się dobrze.
David Heffernan
Jakiej rmwersji używasz ( rm --version)? rm -działa dobrze z GNU coreutils 8.5.
Lekensteyn,
2
Inny wariant:rm ./-
CVN

Odpowiedzi:

60

To było publikowane w FAQ Usenetu dla Uniksa - widzę, że jest w FAQ GNU Core Utility . Było co najmniej pięć różnych metod, ale działa to dobrze:

$ rm ./-

Jeśli nazwa pliku zawiera znaki, których nie można wpisać, użyj:

$ rm -i *

-iFlag prosi o potwierdzenie dla każdego pliku, czy powinien on zostać usunięty lub nie.

wallyk
źródło
1
Lub rm -i - ' - ', jeśli szukasz plików zawierających myślnik i może spacje lub cokolwiek innego.
Hans-Peter Störr
1
rm -i * również dla mnie działał. Dziękuję wallyk!
jgrundstad
39

Usuwanie pliku, którego nazwy zaczynają się od, -to często zadawane pytania, ale wygląda na to, że masz inny problem.

Z rozwiązań wymienionych w pytaniu:

rm -- -

To powinno działać.

rm "-"

To nie różni się od rm -. Cudzysłowy są usuwane przez powłokę, a rmpolecenie widzi tylko pojedynczy myślnik jako argument. Znaki cudzysłowu są przydatne do unikania metaznaków powłoki; łącznik jest specjalny dla rm, a nie dla powłoki.

rm "\-"

Znaki cudzysłowu uciekają przed odwrotnym ukośnikiem, więc próbuje usunąć plik, którego nazwa składa się z dwóch znaków, odwrotnego ukośnika i łącznika.

rm \-

To jest tak jak rm "-"odpowiednik rm -.

Jak to się dzieje, przynajmniej z GNU Coreutils wersję rm, rm -rzeczywiście Usuwa (lub próby usunięcia) pliku, którego nazwa składa się tylko z myślnikiem. Gdyby twój plik miał taką nazwę, już by go nie było. Doszedłem do wniosku, że twój plik ma nazwę, która tylko przypomina myślnik.

ls | cat -A

powinien dać wyobrażenie o tym, jak to się naprawdę nazywa.

Oto skrypt Perla, który właśnie rzuciłem razem, który wyświetli monit o każdy plik w bieżącym katalogu i poprosi o jego usunięcie. Oferowany bez gwarancji, ale krótko go przetestowałem.

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

EDYCJA : Mniej skomplikowane rozwiązanie: jeśli nazwa pliku to tylko jeden znak, rm ?należy go usunąć (wraz z innymi takimi plikami).

Keith Thompson
źródło
13
M-bM-^@M-^Sto interpretacja 3-bajtowej reprezentacji UTF-8 znaku Unicode „EN DASH” 0x2013. Zastanawiam się, czy przypadkowo skopiowałeś go i wkleiłeś ze strony internetowej.
Keith Thompson
7
czy rm -i *nie działa? Wygląda na to, że zrobiłby to samo, co skrypt perla.
user606723,
2
Domyślam się, że pochodzi ze strony internetowej, na którą skierowałem wget. W każdym razie jeszcze raz dziękuję za dokładne rozwiązanie! dbać.
jgrundstad
5
perl -e 'unlink grep {print "remove $ _?"; <STDIN> = ~ / y / i} glob "*" '
Randal Schwartz
6
@RandalSchwartz: Imponująco zwięzłe (i sprawia, że ​​mój mózg trochę boli) - ale wolałbym /^y/iraczej /y/i. W końcu rosyjski użytkownik może wpisać „Nyet”.
Keith Thompson
19

Jeśli chcesz czegoś bezpieczniejszego ...

Spróbuj użyć kombinacji ls i find (działa to na każdy plik, który masz uprawnienia do usunięcia)

Parametr „-i” daje numer i-węzła dla każdej pozycji katalogu ls -li

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

Po uzyskaniu numeru i-węzła ...

find . -inum **27** -exec rm -i {} \;
Sam
źródło
2
+1, ponieważ jest to świetna ogólna odpowiedź na te problemy. Nawiasem mówiąc tam nie potrzeba maszyn -exec rm w niedawne odkrycie, zaledwie użyć Usuń nie
Sirex
2
@Sirex - Myślę, że chodzi o -exec rm -i {}to -i, aby zachęty do usunięcia. Patrzę man findi nie widzę żadnego sposobu, aby to zrobić.
Stephen P
o tak, w tym przypadku. był bardziej wskazówką.
Sirex,
13

Dać rm ./-szansę.

-Jest flaga rozpocząć flagę argument. Jeśli argument zaczniesz od czegoś innego niż a -, w tym przypadku /zostanie przyjęte, że jest to nazwa pliku. Którego chcesz.

A ponieważ filei ./filesą tym samym plikiem, będzie on kierował na plik o nazwie -via ./-.

Petey B.
źródło
8
Zamiast wpisywania 30 znaków, być może byłby bardziej użyteczny, aby wyjaśnić, dlaczego / pomaga parse poprawnie
Ivo Flipse
@ gcb Dziękujemy za proponowaną edycję. Dodałem do tego znaczniki kodu, aby łatwiej było je czytać.
slhck 18.10.11
7

Nie tak naukowy, jak większość innych odpowiedzi, ale odpaliłbym wystąpienie mcdowódcy o północy i po prostu wybrałem i usunąłem plik.

johanvdw
źródło
+1 za sprytne rozwiązanie problemu - i to nawet bez uciekania się do programu GUI.
sleske
7

Próbować:

$ ls -b

aby sprawdzić, czy nazwa pliku ma znaki niedrukowalne.

Noel Yap
źródło
Dlaczego głosowanie negatywne? Biorąc pod uwagę kontynuację , brzmi to jak bardzo dobra sugestia.
Ilmari Karonen
6

Nie znaczy to, że powinno być konieczne użycie Perla tutaj, ale powinno to działać:

perl -e 'unlink "-"'

lub zobaczyć, jaki może być dowolny błąd z powyższym:

perl -e 'unlink "-" or die "Err: $!"'
runrig
źródło
Ta metoda ma tę zaletę, że nie trzeba się martwić o znaki specjalne (inne niż problemy z cytowaniem ciągów).
Kevin Reid
3

Miałem szczęście, używając Nautilusa GNOME do usuwania źle nazwanych plików. Czy korzystasz z serwera X? Jestem pewien, że inne przeglądarki plików też by działały.

Joel Berger
źródło
3

Jeśli

rm -- -

nie działał, nazwa pliku nie jest „tylko łącznikiem”. Jeśli żadne inne pliki nie mają łącznika, możesz spróbować

perl -E'for (@_) { if (/-/) { unlink($_) or die $! } }' -- *
ikegami
źródło
1

Do tej pory otrzymuję „Brak takiego pliku lub katalogu” dla każdej dotychczas opublikowanej metody:

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

Wygląda na to, że mam wersję rm 7.4. Spróbuję zaktualizować i ponownie spróbować tych sugestii. Dziękuję wszystkim za pomoc.

jgrundstad
źródło
1
Zgaduję, że nie ma takiego pliku lub katalogu i być może nazwa pliku zawiera także niewidoczne znaki. (i możesz uzyskać ten sam komunikat o błędzie w perlu z „unlink” - ”lub zgiń„ Err: $! ””). Spróbuj „ls -b”, aby zobaczyć, jaka jest prawdziwa nazwa pliku.
runrig
1

Bardzo lubię używać diredtrybu w emacs do tego typu rzeczy - po prostu „otwórz” katalog w emacs. Możesz łatwo wybierać pliki i oznaczać je do usunięcia.

Inny plakat sugerował użycie dowódcy północy; jest to prawie ten sam pomysł, ale jeśli jesteś już użytkownikiem emacsa, być może jest to wygodniejsze.

Ernest Friedman-Hill
źródło
0

Powinien być w stanie rm -f '-'pracować dla mnie w cygwin

W tym przypadku rm -wydaje się, że działa również na czerwony kapelusz.

Lucas
źródło
w Ubuntu: ~ / jj $ rm -rf '-' ~ / jj $ ls -
rm -też dla mnie działa.
uzsolt
1
Dlaczego -r? Żądanie usunięcia rekurencyjnego, jeśli nie jest ono potrzebne, jest zawsze niebezpieczne w przypadku błędów.
Hans-Peter Störr
@hstoerr, dobry punkt. po prostu habbit. dłonie piszą szybciej niż mózg. edycja odpowiedzi teraz, dziękuję.
Lucas