Як видалити файл, ім'я якого починається з "-" (дефіс ака тире або мінус)?


348

Як ви видалите файл, ім'я якого файла починається з тире (дефіс або мінус) -? Я ssh'd на віддалений сервер OSX, і я маю цей файл у своєму каталозі:

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

Як у світі можна видалити --helpз CLI? Це питання - це те, що я трапляю в різних формах при нагоді, ці файли легко створити, але важко позбутися.

Я спробував використовувати зворотний нахил

rm \-\-help

Я спробував цитати

rm "--help"

Як запобігти інтерпретації символу мінус (дефіс чи дефіс) як варіант?


1
Було б чудово, якби це питання було перейменовано на "Як видалити файл, ім'я якого починається з -".
Сенді

@Sandy Погодився; Мені зазвичай не подобається змінювати значення питання, але в цьому випадку прийнята відповідь є специфічною для цієї проблеми
Michael Mrozek

33
я вважаю це трохи іронічно, що rm --helpнасправді пояснює, як видалити назви файлів, починаючи з -. гарне питання все ж.
lesmana

1
@ jw013 Іноді досвід допоможе досвідченим користувачам зрозуміти, але непомітний і незрозумілий для новонароджених.
іконоборство

1
Я наткнувся на це в системі, використовуючи rm від BusyBox. Все мінімально, включаючи допомогу, тому rm --help не дав жодних підказок.
dslake

Відповіді:


497

Використовуйте "-", щоб зробити rm стоп-розбір параметрів командного рядка, наприклад:

rm -- --help

1
Я знав, що це щось дуже просте на кшталт цього ...
Брайан Рехбін

2
Чи всі версії rmкоманди підтримують --аргумент?
Кіт Томпсон

3
@KeithThompson - це особливість більшості інструментів GNU, тому він не працюватиме на більшості не-GNU ("не-Linux") Unix'es (наприклад, BSD-варіанти або деякі вбудовані системи)
dtech

1
ДЯКУЮ! Це врятувало мені день. І звичайно, це працює на BSD (OSX) та з іншими командами!
raskhadafi

8
@dtech, getopt () та --попередні GNU (SysIII, 1980) та є стандартними / POSIX. Стандартні утиліти, за винятком кількох винятків (на кшталт echo), розуміють --. YMMV для інших команд, якщо вони не використовують API getopt () для аналізу параметрів.
Стефан Шазелас

213

Або ви можете зробити

rm ./--help

7
Це не важливо, але це здається найбільш "правильним".
Джеймс М.

2
Це те, що я пам’ятаю. Використання "rm - --help" - це те, на що я завжди повинен шукати.
user603

25
Цей метод завжди працює навіть для команд, які не обробляють --спеціально.
jw013

І це також працює , щоб уникнути спеціальної обробки з допомогою деяких команд для інших типів (крім опцій) спеціально іменованих аргументів на кшталт -текстових утиліт або cd, то foo=barз awk...
Stéphane Chazelas

1
Це працює, коли файл починається з одного тире, де rm -- <filename>цього не було.
StockB

37

Використовуйте findдля цього:

find . -name '--help' -delete

І це хороший метод, тому що якщо у вас є кілька таких файлів, як цей, який ви можете видалити, ви можете отримати список попереднього перегляду файлів, просто запустивши -deleteспочатку пошук без параметра, а потім, якщо список файлів виглядає добре, просто запустіть це знову с -delete.

Насправді, ви уникаєте rmна користь find(особливо з попереднім попереднім переглядом) - це хороша звичка, яка допоможе вам уникнути помилок, rm *які неминуче кусають вас якийсь день.

Зауважте, що ця знахідка повторюватиметься у всіх ваших підкаталогах, тому ви, можливо, захочете запустити її з таким обмеженням глибини підкаталогу, як це:

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

що обмежує знаходження в поточному каталозі.


Портативно, вам потрібно надати findсписок файлів / dirs, на який слід ознайомитися. Отже find . -name.... -deleteі -maxdepthне є стандартними варіантами.
Стефан Шазелас

21

Відповіді Вегара Нільсена та Едфуха є дуже хорошими та правильними рішеннями подібної проблеми.

Я хочу додати загальну відповідь на це питання, яка дозволяє видалити будь-який файл зі складним ім'ям файлу. Спочатку його номер inode отримується за допомогою ls -iабо якоїсь форми, statа потім файл видаляється шляхом пошуку файлів у поточному каталозі за номером inode та виконанням rmкоманди в файлі з відповідним номером inode

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

Оскільки номери inode є унікальними у кожній файловій системі, ви можете видалити будь-який файл за допомогою цього; unicode або використовуючи символи втечі Це як раз дуже прикро набирати текст, тому я рекомендую додати рядок

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

у ваш .inputrcфайл, якщо ви використовуєте bash. Це дозволяє переглядати список можливих доповнень ( для отримання додаткової інформації ).


5
У цього шляху є дві проблеми: 1) не використовуйте -exec rm, коли ви можете використовувати -delete; 2) отримання inode та використання, що зайве ускладнюється, коли можна просто використовувати:find -name '--help' -delete
aculich

Я не думаю, що це спрацює. Він проходить всі файли в поточному каталозі та всі його підкаталоги, і, нарешті , він все ще викликає rm --help, який все одно не видалить файл. Просто скористайтеся rm ./--help(або rm -i *.
Кіт Томпсон

1
@KeithThompson findпрефіксує шлях аргументу командного рядка до всіх файлів, щоб він запускався rm ./--helpі rm ./sub/dirs/--help. Для виправлення другого потрібно було б додати -maxdepth 1, але все це по суті застосовує рішення @ edfuh більш крутим, звивистим способом і -deleteбезпечніше, ніж -exec rmбудь-коли.
jw013

1
Ще одна проблема з цією командою є те , що повинно бути простір між {}та \;, в іншому випадку він не буде працювати.
Євген S

inodes може бути унікальним, але може бути кілька записів каталогів з одним і тим же inode. Вони називаються жорсткими посиланнями. І вони унікальні лише для файлової системи, тому вам потрібно буде використовувати -xdev. Це не допоможе вам це запустити ls -i --help.
Стефан Шазелас


8

Покрокові інструкції зі створення файлу з тире та пробілів та видалення його.

БУДЬ ОБЕРЕЖНИЙ! Не випадково запускайте rm -rf /чи подібну команду видалення каскаду.

Якщо файл , який ви намагаєтеся видалити включає зірочками або косу риску, не випадково накачати .АБО /*або *або який - або інший групові , які можуть каскадне видалення операційної системи.

Створіть файл під назвою "--yo yo"

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

Спочатку знайдіть його з пошуку:

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

Переконайтесь, що команда find ТІЛЬКИ знаходить один файл, який потрібно видалити:

Потім перейдіть до опції -delete, щоб знайти їх, щоб видалити:

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

Aaaannd його вже немає.


2

Midnight Commander ( mc) - найпростіший, просто вкажіть на нього та натисніть F8;)


3
ОП хоче рішення командного рядка (CLI).
Франческо Турко

1
Midnight Commander - це рішення CLI. Просто встановіть ваші керування пакетами, щоб встановити його. (Це працює навіть над ssh ...) en.wikipedia.org/wiki/Midnight_Commander
daviewales

6
Чим простіше використовувати apt-get install mc || yum install mc; mc різні клавіші зі стрілками та F8rm ./--help ?
Джош

3
@daviewales: Midnight Commander запускається з командного рядка, і він запускається в терміналі, але всі дії клавіатури в межах Midnight Commander не з CLI (Interface Command Line Interface) - вони з інтерфейсу командира Midnight Commander. - Зазвичай утиліти командного рядка можна запускати в рамках сценарію (виняток - історія командного рядка bash)
Peter.O

1

ось рішення, яке я використав, перш ніж знайти цю тему.
використовувати vimдля редагування каталогу:

vim .

потім (in vim) виберіть файл, натисніть del і підтвердьте видалення.
коли ти закінчиш кинути vim:q


0

Ви намагалися додати ім'я каталогів як префікс:

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

Використання каталогу в якості префіксу файлу в цілому допомагає уникнути неправильної інтерпретації символу "мінус" як параметра команди за допомогою функції аналізатора.


1
Я вважаю, що це вже було висвітлено у попередній відповіді .
Kusalananda

-3

Якщо ви хочете перейменувати файл -.bar,, (mv не працюватиме), спробуйте:

cat >foo.bar <-.bar

перед використанням команди:

rm -- -.bar

Ви повинні мати можливість вивчити вміст оригінального файлу в foo.bar


4
Створення копії файлу - не дуже ефективне рішення для його перейменування.
jw013

1
Ви можете використовувати vidir; але це, мабуть, так само (або навіть більше) неефективно - і набагато небезпечніше.
Стівен Менасіан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.