Jak usunąć plik, którego nazwa zaczyna się od „-” (myślnik aka myślnik lub minus)?

348

Jak usunąć plik, którego nazwa pliku zaczyna się od myślnika (myślnik lub minus) -? Jestem ssh'd na zdalnym serwerze OSX i mam ten plik w moim katalogu:

tohru:~ $ ls -l
total 8
-rw-r--r--    1 me  staff  1352 Aug 18 14:33 --help
...

Jak na świecie mogę usunąć --helpz interfejsu CLI? Ten problem pojawia się czasami w różnych formach, pliki te można łatwo utworzyć, ale trudno się ich pozbyć.

Próbowałem użyć odwrotnego ukośnika

rm \-\-help

Próbowałem cytatów

rm "--help"

Jak zapobiec interpretowaniu znaku minus (myślnik lub myślnik) jako opcji?

Bryan Rehbein
źródło
1
Byłoby wspaniale, gdyby zmieniono nazwę tego pytania na „Jak usunąć plik, którego nazwa zaczyna się od -”.
Sandy,
@Sandy uzgodnione; Zwykle nie lubię zmieniać znaczenia pytania, ale w tym przypadku przyjęta odpowiedź jest specyficzna dla tego problemu
Michael Mrozek
33
Uważam, że to trochę ironiczne, że rm --helptak naprawdę wyjaśnia, jak usunąć nazwy plików zaczynające się na -. dobre pytanie jednak.
lesmana
1
@ jw013 Czasami pomoc jest łatwa do zrozumienia dla doświadczonych użytkowników, ale przytłaczająca i myląca dla newbs.
iconoclast
1
Natknąłem się na to w systemie za pomocą rm z BusyBox. Wszystko jest minimalne, łącznie z pomocą, więc rm --help nie dostarczył żadnych wskazówek.
dslake

Odpowiedzi:

497

Użyj „-”, aby rm przestał analizować opcje wiersza poleceń, takie jak:

rm -- --help
Vegar Nilsen
źródło
1
Wiedziałem, że to coś bardzo prostego ...
Bryan Rehbein
2
Czy wszystkie wersje rmpolecenia obsługują --argument?
Keith Thompson,
3
@KeithThompson - jest cechą większości narzędzi GNU, więc nie będzie działać na większości spoza GNU ( „non-Linux”) Unix'es (np wariantach BSD lub niektórych systemów wbudowanych)
Dtech
1
DZIĘKI! To uratowało mi dzień. I oczywiście działa na BSD (OSX) i na innych poleceniach!
raskhadafi
8
@dtech, getopt () i --wcześniej GNU (SysIII, 1980) i są standardem / POSIX. Standardowe narzędzia z wyjątkiem kilku wyjątków (jak echo) rozumieją --. YMMV dla innych poleceń, jeśli nie używają interfejsu API getopt () do analizowania opcji.
Stéphane Chazelas,
213

Lub możesz to zrobić

rm ./--help
edfuh
źródło
7
To nie ma znaczenia, ale wydaje się to najbardziej „właściwe”.
James M.
2
To ten, który pamiętam. Używanie „rm - --help” jest czymś, na co zawsze muszę patrzeć.
user603,
25
Ta metoda zawsze działa nawet w przypadku poleceń, które nie traktują --specjalnie.
jw013,
I to działa również w celu uniknięcia specjalnego traktowania przez niektórych poleceń dla innych typów (oprócz opcji) specjalnie nazwanych argumentów jakby -narzędzi tekstowych lub cdThe foo=barof awk...
Stéphane Chazelas
1
Działa to, gdy plik zaczyna się od pojedynczego myślnika, gdzie rm -- <filename>nie.
StockB
37

Użyj, findaby to zrobić:

find . -name '--help' -delete

Jest to dobra metoda, ponieważ jeśli masz więcej niż kilka takich plików, które możesz usunąć, możesz uzyskać listę podglądu plików, po prostu uruchamiając find bez -deleteopcji, a następnie, jeśli lista plików wygląda dobrze, po prostu uruchom to znowu z -delete.

W rzeczywistości unikanie rmna korzyść find(zwłaszcza z podglądem) jest dobrym nawykiem, który pomoże ci uniknąć błędów rm *, które pewnego dnia nieuchronnie cię ugryzą.

Zauważ jednak, że to wyszukiwanie będzie się powtarzać we wszystkich twoich podkatalogach, więc możesz chcieć uruchomić go z ograniczeniem głębokości podkatalogu, takim jak to:

find . -maxdepth 1 -name '--help' -delete

co ogranicza wyszukiwanie do bieżącego katalogu.

aculich
źródło
Przenośne, musisz podać findlistę plików / katalogów do przejrzenia. Tak find . -name.... -deletei -maxdepthnie są też standardowymi opcjami.
Stéphane Chazelas,
21

Odpowiedzi Vegara Nilsena i edfuha są bardzo dobre i właściwe rozwiązania takiego problemu.

Chcę dodać ogólną odpowiedź na to pytanie, która pozwala usunąć dowolny plik o trudnej nazwie. Najpierw jego numer i-węzła jest uzyskiwany za pomocą ls -ilub w jakiejś formie, stata następnie plik jest usuwany przez wyszukiwanie plików w bieżącym katalogu według numeru i-węzła i wykonanie rmpolecenia na pliku z pasującym numerem i-węzła

find . -inode <inode> -exec rm {}\;

Ponieważ numery i-węzłów są unikalne w każdym systemie plików, można za pomocą tego usunąć dowolny plik; Unicode lub używanie znaków zmiany znaczenia. Pisanie jest zawsze bardzo denerwujące, dlatego polecam dodanie wiersza

TAB: menu-complete             # Tab: Cycles through the command
"\e[Z": menu-complete-backward # Shift-Tab: Cycles backwards

do .inputrcpliku, jeśli używasz bash. Umożliwia to przeglądanie listy możliwych uzupełnień ( w celu uzyskania dalszych informacji ).

Baldur
źródło
5
W ten sposób występują dwa problemy: 1) nie używaj -exec rm, kiedy możesz użyć -delete; 2) uzyskanie i-węzła i korzystanie z niego jest niepotrzebnie nadmiernie skomplikowane, gdy można po prostu użyć:find -name '--help' -delete
aculich
Nie sądzę, żeby to zadziałało. Przechodzi przez wszystkie pliki w bieżącym katalogu i wszystkich jego podkatalogach, a mimo to wciąż wywołuje rm --help, co nadal nie usuwa pliku. Wystarczy użyć rm ./--help(lub rm -i *.
Keith Thompson
1
@KeithThompson poprzedza findścieżkę argumentu wiersza poleceń do wszystkich plików, aby działał rm ./--helpi rm ./sub/dirs/--help. Aby naprawić drugi, należałoby dodać -maxdepth 1, ale to wszystko zasadniczo polega na zastosowaniu rozwiązania @ edfuh w bardziej okrągły, zawiły sposób i -deletejest bezpieczniejsze niż w każdym razie -exec rm.
jw013,
1
Kolejnym problemem związanym z tym poleceniem jest to, że musi być spacja między {}i \;, w przeciwnym razie nie zadziała.
Eugene S
i-węzły mogą być unikalne, ale może istnieć kilka pozycji katalogu z tym samym i-węzłem. Są to tak zwane twarde linki. I są one unikatowe dla każdego systemu plików, więc musisz użyć -xdev. To ci nie pomoże ls -i --help.
Stéphane Chazelas,
11

Brutalne rozwiązanie:

perl -e "unlink '--help' or die 'Could not unlink.';"

perl -e "rmdir '-d' or die 'Could not rmdir.';"
Thomas L. Holaday
źródło
8

Linux Przewodnik tworzenia pliku z myślnikami i spacjami, a następnie usuwania go.

BĄDŹ OSTROŻNY! Nie uruchamiaj przypadkowo rm -rf /podobnego polecenia kasowania.

Jeśli plik, który próbujesz usunąć obejmuje gwiazdki lub ukośniki, nie przypadkowo pompować .Or /*lub *lub inny symbol wieloznaczny, który mógłby kaskadowego usuwania systemu operacyjnego.

Utwórz plik o nazwie „--yo yo”

eric@dev ~ $ touch -- "--yo yo"
eric@dev ~ $ ls
bin  --yo yo

Najpierw znajdź za pomocą find:

eric@dev ~ $ find . -name "*--yo yo*"
./--yo yo

Upewnij się, że polecenie find TYLKO odnajduje JEDEN plik, który chcesz usunąć:

Następnie przekaż opcję -delete, aby znaleźć, aby je usunąć:

eric@dev ~ $ find . -name "*--yo yo*" -delete
eric@dev ~ $ ls
bin  

Aaaannd już go nie ma.

Eric Leschinski
źródło
2

Midnight Commander ( mc) jest najłatwiejszy, po prostu wskaż go i naciśnij F8;)

Marcin
źródło
3
OP chce rozwiązania wiersza poleceń (CLI).
Francesco Turco
1
Midnight Commander JEST rozwiązaniem CLI. Wystarczy zainstalować menedżera pakietów. (Działa nawet na ssh ...) en.wikipedia.org/wiki/Midnight_Commander
daviewales
6
W jaki sposób apt-get install mc || yum install mc; mc różne klawisze strzałek i F8 są łatwiejsze niż rm ./--help?
Josh
3
@daviewales: Program Midnight Commander jest uruchamiany z wiersza poleceń i działa w terminalu, ale wszystkie operacje na klawiaturze w programie Midnight Commander nie są wykonywane z poziomu interfejsu wiersza poleceń (CLI) - pochodzą one z interfejsu Midnight Commander. - Zazwyczaj narzędzia wiersza poleceń można uruchamiać w skrypcie (wyjątkiem jest historia wiersza poleceń bash)
Peter.O
1

oto rozwiązanie, którego użyłem przed znalezieniem tego wątku.
użyj vimdo „edycji” katalogu:

vim .

następnie (in vim) wybierz plik, naciśnij del i potwierdź usunięcie.
kiedy skończysz, przestań vim z:q

atti
źródło
0

Czy próbowałeś dodać nazwę katalogu jako prefiks:

$ rm ./-filename.txt dirname/-filename2.txt
$ mv ./-filename.txt filename.txt
$ cp teste ./-teste

Korzystanie z katalogu jako przedrostka pliku pomaga uniknąć błędnej interpretacji znaku „minus” jako opcji polecenia przez funkcję analizatora składni.

Paulo Henrique Lellis Gonalves
źródło
1
Wierzę, że zostało to już omówione we wcześniejszej odpowiedzi .
Kusalananda
-3

Jeśli chcesz zmienić nazwę pliku, -.bar(mv nie będzie działać), spróbuj tego:

cat >foo.bar <-.bar

przed użyciem polecenia:

rm -- -.bar

Powinieneś być w stanie sprawdzić zawartość oryginalnego pliku w foo.bar

Stephen Menasian
źródło
4
Wykonanie kopii pliku nie jest bardzo skutecznym rozwiązaniem do zmiany jego nazwy.
jw013,
1
Możesz użyć vidir; ale jest to prawdopodobnie tak samo (lub nawet bardziej) nieefektywne - i znacznie bardziej niebezpieczne.
Stephen Menasian