Bagaimana cara menghapus file yang namanya dimulai dengan "-" (tanda hubung alias minus atau minus)?

349

Bagaimana Anda menghapus file yang nama filenya dimulai dengan tanda hubung (tanda hubung atau minus) -? Saya ssh'd ke server OSX jarak jauh dan saya memiliki file ini di direktori saya:

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

Bagaimana saya bisa menghapus --helpdari CLI? Masalah ini adalah sesuatu yang saya temui dalam berbagai bentuk pada kesempatan, file-file ini mudah dibuat, tetapi sulit untuk dihilangkan.

Saya telah mencoba menggunakan backslash

rm \-\-help

Saya sudah mencoba kutipan

rm "--help"

Bagaimana cara mencegah karakter minus (tanda hubung atau tanda hubung) ditafsirkan sebagai opsi?

Bryan Rehbein
sumber
1
Akan lebih bagus jika pertanyaan ini diubah namanya menjadi "Bagaimana cara menghapus file yang namanya dimulai dengan -".
Sandy
@Sandy Setuju; Saya biasanya tidak suka mengubah makna pertanyaan, tetapi dalam hal ini jawaban yang diterima khusus untuk masalah ini
Michael Mrozek
33
saya merasa agak ironis yang rm --helpsebenarnya menjelaskan cara menghapus nama file yang dimulai dengan a -. pertanyaan yang bagus.
lesmana
1
@ jw013 Terkadang bantuannya mudah dipahami oleh pengguna berpengalaman, tetapi membingungkan dan membingungkan bagi newb.
iconoclast
1
Saya mengalami ini pada sistem menggunakan rm dari BusyBox. Semuanya minimal, termasuk bantuan, jadi rm --help tidak memberikan petunjuk apa pun.
dslake

Jawaban:

497

Gunakan "-" untuk membuat rm stop opsi penguraian perintah, seperti ini:

rm -- --help
Vegar Nilsen
sumber
1
Saya tahu itu sesuatu yang sangat sederhana seperti ini ...
Bryan Rehbein
2
Apakah semua versi rmperintah mendukung --argumen?
Keith Thompson
3
@KeithThompson - adalah fitur dari sebagian besar alat GNU, sehingga tidak akan berfungsi pada sebagian besar non-GNU ("non-Linux") Unix'es (misalnya varian BSD atau beberapa sistem tertanam)
dtech
1
TERIMA KASIH! Itu menyelamatkan hari saya. Dan tentu saja ini berfungsi pada BSD (OSX) dan dengan perintah lain!
raskhadafi
8
@dtech, getopt () dan --sebelum GNU (SysIII, 1980) dan standar / POSIX. Utilitas standar kecuali untuk beberapa pengecualian (seperti echo) mengerti --. YMMV untuk perintah lain jika mereka tidak menggunakan getopt () API untuk menguraikan opsi.
Stéphane Chazelas
214

Atau Anda bisa melakukannya

rm ./--help
edfuh
sumber
7
Bukan itu penting tetapi ini tampaknya yang paling "tepat".
James M.
2
Ini yang saya ingat. Menggunakan "rm - --help" adalah sesuatu yang selalu harus saya cari.
user603
25
Metode ini selalu berfungsi bahkan untuk perintah yang tidak memperlakukan --secara khusus.
jw013
Dan ia juga bekerja untuk menghindari perlakuan khusus oleh beberapa perintah untuk jenis lain (di samping opsi) dari argumen khusus bernama seperti -utilitas teks atau cd, yang foo=bardari awk...
Stéphane Chazelas
1
Ini berfungsi ketika file dimulai dengan satu tanda hubung, di mana rm -- <filename>tidak.
StockB
37

Gunakan finduntuk melakukannya:

find . -name '--help' -delete

Dan ini adalah metode yang baik karena jika Anda memiliki lebih dari beberapa file seperti ini yang dapat Anda hapus, Anda bisa mendapatkan daftar pratinjau file dengan hanya menjalankan find tanpa -deleteopsi terlebih dahulu, dan kemudian jika daftar file terlihat bagus jalankan saja lagi dengan -delete.

Bahkan, Anda menghindari rmmendukung find(terutama dengan pratinjau terlebih dahulu) adalah kebiasaan baik yang akan membantu Anda menghindari kesalahan dengan rm *yang pasti akan menggigit Anda suatu hari nanti.

Catatan, meskipun, penemuan itu akan berulang melalui semua subdirektori Anda, jadi Anda mungkin ingin menjalankannya dengan batasan kedalaman subdirektori seperti ini:

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

yang membatasi pencarian ke direktori saat ini.

aculich
sumber
Portable, Anda perlu memberikan finddaftar file / dir untuk melihat. Jadi find . -name.... -deletedan -maxdepthjuga bukan opsi standar.
Stéphane Chazelas
21

Jawaban Vegar Nilsen dan edfuh sangat baik dan solusi yang tepat untuk masalah seperti ini.

Saya ingin menambahkan respons umum terhadap pertanyaan ini yang memungkinkan Anda menghapus file apa pun dengan nama file yang sulit. Pertama nomor inode-nya diperoleh dengan menggunakan ls -iatau beberapa bentuk statdan kemudian file dihapus dengan mencari file dalam direktori saat ini dengan nomor inode dan menjalankan rmperintah pada file dengan nomor inode yang cocok.

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

Karena nomor inode unik di setiap sistem file, Anda dapat menghapus file apa pun menggunakan ini; unicode atau menggunakan karakter escape. Ini adalah cara yang sangat menjengkelkan untuk mengetik jadi saya akan merekomendasikan menambahkan baris

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

ke dalam .inputrcfile Anda jika Anda menggunakan bash. Ini memungkinkan Anda untuk menelusuri daftar kemungkinan penyelesaian ( untuk informasi lebih lanjut ).

Baldur
sumber
5
Cara ini memiliki dua masalah: 1) jangan gunakan -exec rm saat Anda bisa menggunakan -delete; 2) mendapatkan inode dan menggunakan yang terlalu rumit ketika Anda hanya dapat menggunakan:find -name '--help' -delete
aculich
Saya tidak berpikir itu akan berhasil. Itu melintasi semua file dalam direktori saat ini dan semua subdirektori, dan setelah semua itu masih memanggil rm --help, yang masih tidak akan menghapus file. Cukup gunakan rm ./--help(atau rm -i *.
Keith Thompson
1
@KeithThompson findawalan jalur argumen baris perintah ke semua file, jadi itu akan berjalan rm ./--helpdan rm ./sub/dirs/--help. Untuk memperbaiki yang kedua, kita harus menambahkan -maxdepth 1, tetapi semua ini pada dasarnya menerapkan solusi @ edfuh dengan cara yang lebih bundaran, berbelit-belit, dan -deletelebih aman daripada yang lainnya -exec rm.
jw013
1
Satu lagi masalah dengan perintah ini adalah harus ada ruang di antara {}dan \;, jika tidak, tidak akan berhasil.
Eugene S
inode mungkin unik tetapi mungkin ada beberapa entri direktori dengan inode yang sama. Itu disebut hardlink. Dan mereka hanya unik per sistem file, jadi Anda harus menggunakannya -xdev. Itu tidak akan membantu Anda menjalankannya ls -i --help.
Stéphane Chazelas
11

Solusi brutal:

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

perl -e "rmdir '-d' or die 'Could not rmdir.';"
Thomas L Holaday
sumber
8

Linux Walkthrough membuat file dengan tanda hubung dan spasi, lalu menghapusnya.

HATI-HATI! Jangan secara tidak sengaja menjalankan rm -rf /perintah penghapusan kaskade atau sejenisnya.

Jika file yang Anda coba hapus menyertakan tanda bintang atau garis miring, jangan memompa secara tidak sengaja .atau /*atau *atau beberapa wildcard lain yang dapat menghapus sistem operasi Anda.

Buat file bernama "--yo yo"

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

Pertama, temukan dengan find:

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

Pastikan perintah find ONLY menemukan SATU file yang ingin Anda hapus:

Kemudian berikan opsi -delete untuk menemukan, untuk menghapusnya:

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

Dan itu hilang.

Eric Leschinski
sumber
2

Midnight Commander ( mc) adalah yang termudah, cukup arahkan dan tekan F8;)

Marcin
sumber
3
OP menginginkan solusi command line (CLI).
Francesco Turco
1
Midnight Commander ADALAH solusi CLI. Cukup gunakan palungan paket Anda untuk menginstalnya. (Bahkan berfungsi lebih dari ssh ...) en.wikipedia.org/wiki/Midnight_Commander
daviewales
6
Bagaimana apt-get install mc || yum install mc; mc berbagai tombol panah dan F8 lebih mudah daripada rm ./--help?
Josh
3
@daviewales: Midnight Commander dimulai dari baris perintah, dan itu berjalan di terminal, tetapi semua aksi keyboard dalam Midnight Commander bukan dari CLI (Command Line Interface) - mereka berasal dari Midnight Commander's Interface. - Biasanya, utilitas baris perintah dapat dijalankan dalam skrip (pengecualian adalah sejarah baris perintah bash)
Peter.O
1

inilah solusi yang saya gunakan sebelum menemukan utas ini.
gunakan vimuntuk 'mengedit' direktori:

vim .

lalu (dalam vim) pilih file Anda, tekan del dan konfirmasi penghapusan.
ketika Anda selesai berhenti dengan:q

atti
sumber
0

Sudahkah Anda mencoba menambahkan nama direktori sebagai awalan:

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

Menggunakan direktori sebagai awalan file secara umum membantu menghindari interpretasi yang salah dari karakter "minus" sebagai opsi perintah oleh fungsi parser.

Paulo Henrique Lellis Gonalves
sumber
1
Saya yakin ini sudah tercakup dalam jawaban sebelumnya .
Kusalananda
-3

Jika Anda ingin mengganti nama file -.bar,, (mv tidak akan berfungsi), coba ini:

cat >foo.bar <-.bar

sebelum menggunakan perintah:

rm -- -.bar

Anda harus dapat memeriksa konten file asli di foo.bar

Stephen Menasian
sumber
4
Membuat salinan file bukanlah solusi yang sangat efisien untuk mengganti nama file.
jw013
1
Anda bisa menggunakan vidir; tetapi itu mungkin sama (atau bahkan lebih) tidak efisien - dan jauh lebih berbahaya.
Stephen Menasian