Как удалить файл, имя которого начинается с «-» (дефис или минус)?


349

Как удалить файл, имя которого начинается с тире (дефис или минус) -? Я 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 Согласен; Обычно я не люблю менять значение вопроса, но в этом случае принятый ответ является специфическим для этой проблемы
Майкл Мрозек

33
я нахожу это немного ироничным, что на rm --helpсамом деле объясняет, как удалить имена файлов, начинающиеся с -. хороший вопрос тем не менее.
Lesmana

1
@ jw013 Иногда помощь понятна для опытных пользователей, но для новичков она ошеломительна.
иконоборчество

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

Ответы:


497

Используйте «-», чтобы rm прекратил синтаксический анализ параметров командной строки, например так:

rm -- --help

1
Я знал, что это было что-то очень простое, как это ...
Брайан Ребейн

2
Все версии rmкоманды поддерживают --аргумент?
Кит Томпсон

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

1
СПАСИБО! Это спасло мой день. И, конечно, он работает на BSD (OSX) и с другими командами!
Расхадафи

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

214

Или вы можете сделать

rm ./--help

7
Не то, чтобы это имело значение, но это кажется самым «правильным».
Джеймс М.

2
Это тот, который я помню. Использование «rm - --help» - это то, что мне всегда нужно искать.
user603 21.09.10

25
Этот метод всегда работает даже для команд, которые не обрабатывают --специально.
jw013

И это также работает, чтобы избежать специальной обработки некоторыми командами для других типов (кроме параметров) специально названных аргументов, таких как -текстовые утилиты или cd, foo=barиз awk...
Стефан Шазелас

1
Это работает, когда файл начинается с одной черты, где rm -- <filename>нет.
StockB

37

Используйте findдля этого:

find . -name '--help' -delete

И это хороший метод, потому что, если у вас есть несколько таких файлов, которые вы можете удалить, вы можете получить список предварительного просмотра файлов, просто запустив find без -deleteопции, а затем, если список файлов выглядит хорошо, просто запустите это снова с -delete.

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

Однако обратите внимание, что поиск будет проходить через все ваши подкаталоги, поэтому вы можете запустить его с ограничением глубины подкаталога, например так:

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

который ограничивает поиск текущим каталогом.


В частности, вам нужно предоставить findсписок файлов / каталогов для просмотра. Так find . -name.... -deleteи -maxdepthне являются стандартными вариантами.
Стефан Шазелас

21

Ответы Вегара Нильсена и Эдфуха очень хорошие и правильные решения такой проблемы.

Я хочу добавить общий ответ на этот вопрос, который позволяет вам удалить любой файл со сложным именем файла. Сначала его номер inode получается с использованием ls -iили некоторой формы, statа затем файл удаляется путем поиска файлов в текущем каталоге по номеру inode и выполнения rmкоманды для файла с соответствующим номером inode

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

Поскольку номера инодов уникальны в каждой файловой системе, вы можете удалить любой файл, используя это; Unicode или использование escape-символов. Это очень раздражает, поэтому я рекомендую добавить строку

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) получение инода и его использование без необходимости усложняется, когда вы можете просто использовать: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
Еще одна проблема с этой командой заключается в том, что между {}и должен быть пробел \;, иначе она не будет работать.
Евгений С

Иноды могут быть уникальными, но может быть несколько записей каталога с одним и тем же индексом. Это так называемые жесткие ссылки. И они уникальны только для файловой системы, поэтому вам придется использовать их -xdev. Это не поможет вам запустить это ls -i --help.
Стефан Шазелас

11

Брутальное решение:

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

perl -e "rmdir '-d' or die 'Could not rmdir.';"

8

Linux Пошаговое руководство по созданию файла с тире и пробелами, а затем его удалению.

БЫТЬ ОСТОРОЖЕН! Не запускайте случайно rm -rf /или аналогичную команду каскадного удаления.

Если ваш файл, который вы пытаетесь удалить, включает в себя звездочки или косые черты, не используйте случайно .или, /*или, *или иные другие символы, которые могут каскадно удалить вашу операционную систему.

Создайте файл с именем "--yo yo"

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

Сначала найдите это с помощью find:

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

Убедитесь, что команда find ТОЛЬКО находит ОДИН файл, который вы хотите удалить:

Затем передайте опцию -delete, чтобы найти и удалить их:

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

Ааа, и это ушло.


2

Midnight Commander ( mc) самый простой, просто наведите на него курсор и нажмите F8;)


3
OP хочет решение командной строки (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 (интерфейс командной строки) - они из интерфейса Midnight Commander. - Обычно утилиты командной строки можно запускать в скрипте (исключение составляет история командной строки bash)
Peter.O

1

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

vim .

затем (в vim) выберите ваш файл, нажмите Del и подтвердите удаление.
когда вы закончите, выйдите из Vim:q


0

Вы пытались добавить имя каталога в качестве префикса:

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

Использование каталога в качестве префикса файла в целом помогает избежать ошибочной интерпретации символа «минус» как параметра команды функцией синтаксического анализа.


1
Я считаю, что это уже было рассмотрено в предыдущем ответе .
Кусалананда

-3

Если вы хотите переименовать файл, -.bar(mv не будет работать), попробуйте это:

cat >foo.bar <-.bar

перед использованием команды:

rm -- -.bar

Вы должны быть в состоянии проверить содержимое исходного файла в foo.bar


4
Создание копии файла - не очень эффективное решение для его переименования.
jw013

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