Bagaimana cara menghapus file di Linux yang namanya HANYA sebuah tanda hubung, seperti pada "-"

33

Saya sudah mencoba

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

Memberi Perl kesempatan

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

...dan...

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

Bantuan apa pun akan sangat dihargai, orang bijak.

jgrundstad
sumber
Karena penasaran, bagaimana itu bisa sampai di sana?
Petey B
2
Itu adalah hasil dari wget yang dibangun dengan buruk: "wget ​​-q -O - someserver.org/s/ip "
53
Mengingatkan saya pada saat seorang rekan membuat file bernama *. Kisah ini tidak berakhir dengan baik.
David Heffernan
rmVersi apa yang Anda gunakan ( rm --version)? rm -berfungsi dengan baik dengan GNU coreutils 8.5.
Lekensteyn
2
Varian lain:rm ./-
CVn

Jawaban:

60

Ini digunakan untuk diposting di FAQ Usenet untuk Unix — Saya melihatnya di FAQ Utilitas Inti GNU . Setidaknya ada lima metode yang berbeda, tetapi ini bekerja dengan baik:

$ rm ./-

Jika nama file berisi karakter yang tidak dapat di ketik, maka gunakan:

$ rm -i *

The -ibendera meminta konfirmasi untuk setiap file jika harus dihapus atau tidak.

wallyk
sumber
1
Atau rm -i - ' - ' jika Anda mencari file yang berisi tanda hubung dan mungkin beberapa spasi atau apa pun.
Hans-Peter Störr
1
rm -i * juga bekerja untuk saya. Terima kasih wallyk!
jgrundstad
39

Menghapus file yang namanya dimulai dengan -FAQ, tetapi sepertinya Anda memiliki masalah yang berbeda.

Solusi yang Anda sebutkan dalam pertanyaan:

rm -- -

Itu seharusnya bekerja.

rm "-"

Itu tidak berbeda dari rm -. Kutipan dilucuti oleh shell, dan rmperintah hanya melihat tanda hubung tunggal sebagai argumen. Tanda kutip berguna untuk keluar dari karakter meta shell; tanda hubung khusus untuk rm, bukan untuk shell.

rm "\-"

Tanda kutip lolos dari garis miring terbalik, jadi ini mencoba untuk menghapus file yang namanya terdiri dari dua karakter, garis miring terbalik dan tanda hubung.

rm \-

Ini seperti rm "-", setara dengan rm -.

Seperti yang terjadi, setidaknya dengan versi GNU coreutils rm, rm -sebenarnya menghapus (atau upaya untuk menghapus) file yang namanya hanya terdiri dari tanda hubung. Jika file Anda memiliki nama itu, itu akan hilang sekarang. Saya menyimpulkan bahwa file Anda memiliki nama yang hanya terlihat seperti tanda hubung.

ls | cat -A

harus memberi gambaran tentang apa sebutannya.

Ini skrip Perl yang baru saja saya letakkan bersama yang akan meminta Anda untuk setiap file di direktori saat ini dan bertanya apakah akan menghapusnya. Ditawarkan tanpa garansi, tapi saya sudah mengujinya secara singkat.

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

EDIT : Solusi yang tidak terlalu rumit: jika nama file hanya satu karakter, maka rm ?harus menghapusnya (bersama dengan file lain yang sejenis).

Keith Thompson
sumber
13
M-bM-^@M-^Sadalah rendition dari representasi 3-byte UTF-8 dari karakter Unicode "EN DASH", 0x2013. Saya ingin tahu apakah Anda secara tidak sengaja menyalin dan menempelnya dari halaman web.
Keith Thompson
7
tidak rm -i *tidak bekerja? Sepertinya itu akan melakukan hal yang sama dengan skrip perl.
user606723
2
Saya menduga itu berasal dari halaman web di mana saya menunjuk wget. Bagaimanapun, terima kasih lagi untuk solusi menyeluruh! hati hati.
jgrundstad
5
perl -e 'batalkan tautan grep {print "remove $ _?"; <STDIN> = ~ / y / i} glob "*" '
Randal Schwartz
6
@RandalSchwartz: Sangat singkat (dan membuat otakku sedikit sakit) - tapi aku lebih /^y/isuka daripada /y/i. Lagi pula, pengguna Rusia mungkin mengetik "Nyet".
Keith Thompson
19

Jika Anda menginginkan sesuatu yang lebih aman ...

Coba gunakan kombinasi ls dan temukan (ini berfungsi untuk semua file yang Anda miliki izin untuk menghapus)

Parameter '-i' akan memberi Anda nomor inode untuk setiap entri direktori ls -li

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

Setelah Anda memiliki nomor inode ...

find . -inum **27** -exec rm -i {} \;
Sam
sumber
2
Memberi +1 karena ini adalah jawaban umum yang bagus untuk masalah ini. Ngomong-ngomong, tidak perlu menggunakan -exec rm di find terbaru, cukup gunakan -delete
Sirex
2
@ Sirex - Saya pikir intinya -exec rm -i {}adalah -iuntuk meminta penghapusan. Saya melihat man finddan tidak melihat cara untuk melakukan itu.
Stephen P
oh ya, dalam hal ini. lebih tip.
Sirex
13

Berikan rm ./-mencoba.

Ini -adalah bendera untuk memulai argumen bendera. Jika Anda memulai argumen dengan apa pun kecuali a -, dalam hal ini /, itu akan menganggap itu adalah nama file. Itu yang kamu inginkan.

Dan karena filedan ./filemerupakan file yang sama, itu akan menargetkan file bernama -via ./-.

Petey B
sumber
8
Daripada mengetik 30 karakter, mungkin akan lebih bermanfaat untuk menjelaskan mengapa / membantu mengurai dengan benar
Ivo Flipse
@ gcb Terima kasih atas pengeditan yang diusulkan. Saya menambahkan markup kode untuk itu, jadi akan lebih mudah dibaca.
slhck
7

Bukan sebagai culun seperti kebanyakan jawaban lain, tapi saya akan menjalankan contoh mc, komandan tengah malam, dan hanya memilih dan menghapus file.

johanvdw
sumber
+1 untuk secara cerdik melangkahi masalah - dan bahkan tanpa menggunakan program GUI.
sleske
7

Mencoba:

$ ls -b

untuk melihat apakah nama file memiliki karakter yang tidak patut dicetak.

Noel Yap
sumber
Mengapa downvote? Mengingat tindak lanjutnya , ini terdengar seperti saran yang sangat bagus.
Ilmari Karonen
6

Bukan berarti harus menggunakan perl di sini, tetapi ini harus bekerja:

perl -e 'unlink "-"'

atau untuk melihat apa kesalahan apa pun di atas:

perl -e 'unlink "-" or die "Err: $!"'
runrig
sumber
Metode ini memiliki keuntungan karena tidak ada karakter khusus yang perlu dikhawatirkan (selain masalah mengutip string).
Kevin Reid
3

Saya beruntung menggunakan Nautilus GNOME untuk menghapus file-file dengan nama buruk. Apakah Anda menjalankan X-server? Saya yakin browser file lain juga akan berfungsi.

Joel Berger
sumber
3

Jika

rm -- -

tidak berfungsi, nama file bukan "hanya tanda hubung". Jika tidak ada file lain yang memiliki tanda hubung di dalamnya, Anda dapat mencoba

perl -E'for (@_) { if (/-/) { unlink($_) or die $! } }' -- *
ikegami
sumber
1

Sejauh ini saya mendapatkan "Tidak ada file atau direktori" untuk setiap metode yang diposting sejauh ini:

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

Tampaknya saya punya rm versi 7.4. Saya akan mencoba memutakhirkan dan mencoba kembali saran ini. Terima kasih semuanya telah membantu.

jgrundstad
sumber
1
Saya menduga tidak ada file atau direktori seperti itu, dan mungkin nama file juga mengandung beberapa karakter yang tidak terlihat. (dan Anda bisa mendapatkan pesan kesalahan yang sama di perl dengan 'batalkan tautan "-" atau mati "Err: $!"'). Coba "ls -b" untuk melihat nama file sebenarnya.
runrig
1

Saya sangat suka menggunakan diredmode di emacs untuk hal semacam ini - cukup "buka" direktori di emacs. Anda dapat dengan mudah memilih file dan menandainya untuk dihapus.

Poster lain menyarankan menggunakan komandan tengah malam; ini ide yang hampir sama, tetapi jika Anda sudah menjadi pengguna emacs mungkin lebih nyaman.

Ernest Friedman-Hill
sumber
0

Seharusnya bisa rm -f '-'bekerja untuk saya di cygwin

Untuk hal itu, rm -tampaknya juga bekerja pada topi merah.

Lucas
sumber
di Ubuntu: ~ / jj $ rm -rf '-' ~ / jj $ ls -
rm -bekerja untuk saya juga.
uzsolt
1
Kenapa -r? Meminta penghapusan rekursif jika Anda tidak membutuhkannya selalu berbahaya jika terjadi kesalahan ejaan.
Hans-Peter Störr
@ hstoerr, poin bagus. hanya habbit. tipe tangan lebih cepat dari otak. mengedit respons sekarang, terima kasih.
Lucas