Làm cách nào để xóa một tệp trong Linux có tên giống như nó CHỈ là một dấu gạch nối, như trong Tiếng -


33

Tôi đã thử

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

Đã cho Perl một phát súng

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

... và ...

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

Bất kỳ trợ giúp sẽ được nhiều đánh giá cao, folks khôn ngoan.


Vì tò mò, làm thế nào mà nó đến đó?
Petey B

2
Đó là kết quả của một wget được xây dựng kém: "wget ​​-q -O - someserver.org/s/ip "

53
Nhắc tôi nhớ về thời gian một đồng nghiệp đã tạo một tệp có tên *. Câu chuyện này đã không kết thúc tốt đẹp.
David Heffernan

Có gì rmphiên bản bạn đang sử dụng ( rm --version)? rm -hoạt động tốt với GNU coreutils 8.5.
Lekensteyn

2
Một biến thể khác:rm ./-
CVn

Câu trả lời:


60

Điều này đã từng được đăng trong Câu hỏi thường gặp về Usenet dành cho Unix Tôi thấy nó nằm trong Câu hỏi thường gặp về tiện ích GNU Core . Có ít nhất năm phương pháp khác nhau, nhưng phương pháp này hoạt động tốt:

$ rm ./-

Nếu tên tệp chứa các ký tự không thể tìm thấy, thì hãy sử dụng:

$ rm -i *

Các -ilá cờ yêu cầu xác nhận cho mỗi tập tin nếu nó cần được loại bỏ hay không.


1
Hoặc rm -i - ' - ' nếu bạn đang tìm kiếm tệp chứa dấu gạch ngang và có thể một số khoảng trắng hoặc bất cứ thứ gì.
Hans-Peter Störr

1
rm -i * cũng làm việc cho tôi Cảm ơn wallyk!
jgrundstad

39

Xóa một tệp có tên bắt đầu bằng -một Câu hỏi thường gặp, nhưng có vẻ như bạn đã gặp một vấn đề khác.

Trong số các giải pháp bạn đề cập trong câu hỏi:

rm -- -

Cần làm việc.

rm "-"

Điều đó không khác rm -. Các trích dẫn được tước bởi shell và rmlệnh chỉ xem dấu gạch nối đơn làm đối số. Dấu ngoặc kép rất hữu ích để thoát khỏi các siêu ký tự vỏ; dấu gạch nối là đặc biệt rm, không phải vỏ.

rm "\-"

Dấu ngoặc kép thoát khỏi dấu gạch chéo ngược, vì vậy điều này cố gắng xóa một tệp có tên bao gồm hai ký tự, dấu gạch chéo ngược và dấu gạch nối.

rm \-

Điều này cũng giống như rm "-", tương đương với rm -.

Khi điều đó xảy ra, ít nhất là với phiên bản GNU coreutils rm, rm -thực sự xóa (hoặc cố gắng xóa) một tệp có tên chỉ chứa một dấu gạch nối. Nếu tập tin của bạn có tên đó, nó sẽ biến mất ngay bây giờ. Tôi kết luận rằng tệp của bạn có một tên chỉ trông giống như một dấu gạch nối.

ls | cat -A

nên đưa ra một ý tưởng về những gì nó thực sự được gọi là.

Đây là một tập lệnh Perl tôi vừa ném vào nhau sẽ nhắc bạn cho từng tệp trong thư mục hiện tại và hỏi xem có nên xóa nó không. Được cung cấp mà không có bảo hành, nhưng tôi đã thử nghiệm nó một cách ngắn gọn.

#!/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 : Một giải pháp ít phức tạp hơn: nếu tên tệp chỉ là một ký tự, thì rm ?nên xóa nó (cùng với bất kỳ tệp nào khác như vậy).


13
M-bM-^@M-^Slà biểu hiện của biểu diễn UTF-8 3 byte của ký tự Unicode "EN DASH", 0x2013. Tôi tự hỏi nếu bạn vô tình sao chép và dán nó từ một trang web.
Keith Thompson

7
đã rm -i *không hoạt động? Có vẻ như nó sẽ làm điều tương tự như kịch bản perl.
dùng606723

2
Tôi đoán nó bắt nguồn từ trang web mà tôi đã chỉ ra wget. Trong mọi trường hợp, cảm ơn một lần nữa cho giải pháp kỹ lưỡng! bảo trọng.
jgrundstad

5
perl -e 'hủy liên kết grep {in "xóa $ _?"; <STDIN> = ~ / y / i} toàn cầu "*" '
Randal Schwartz

6
@RandalSchwartz: Ấn tượng ngắn gọn (và khiến não tôi bị tổn thương một chút) - nhưng tôi muốn /^y/ihơn là /y/i. Rốt cuộc, một người dùng Nga có thể gõ "Nyet".
Keith Thompson

19

Nếu bạn muốn một cái gì đó an toàn hơn ...

Hãy thử sử dụng kết hợp ls và find (cách này hiệu quả với mọi tệp bạn có quyền xóa)

Tham số '-i' sẽ cung cấp cho bạn số inode cho mỗi mục nhập thư mục ls -li

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

Khi bạn có số inode ...

find . -inum **27** -exec rm -i {} \;

2
+1 vì đây là một câu trả lời chung tuyệt vời cho những vấn đề này. Nhân tiện, không cần sử dụng -exec rm trong những lần tìm gần đây, chỉ cần sử dụng -delete
Sirex

2
@Sirex - Tôi nghĩ rằng vấn đề -exec rm -i {}-inhắc nhở để loại bỏ. Tôi đang nhìn man findvà không thấy cách nào để làm điều đó.
Stephen P

Ồ vâng, trong trường hợp này. là một mẹo.
Sirex

13

Hãy rm ./-thử.

Đây -là một cờ để bắt đầu một đối số cờ. Nếu bạn bắt đầu đối số với bất cứ điều gì ngoại trừ a -, trong trường hợp này /, nó sẽ cho rằng đó là tên tệp. Đó là những gì bạn muốn.

Và vì file./filelà cùng một tệp, nó sẽ nhắm mục tiêu tệp có tên -thông qua ./-.


8
Thay vì nhập 30 ký tự, có lẽ sẽ hữu ích hơn khi giải thích lý do tại sao / giúp phân tích chính xác
Ivo Flipse

@gcb Cảm ơn bạn đã chỉnh sửa. Tôi đã thêm đánh dấu mã vào đó, vì vậy nó sẽ dễ đọc hơn.
slhck

7

Không táo bạo như hầu hết các câu trả lời khác, nhưng tôi sẽ kích hoạt một ví dụ về mc, chỉ huy nửa đêm, và chỉ cần chọn và xóa tệp.


+1 để xử lý vấn đề một cách khéo léo - và thậm chí không cần dùng đến chương trình GUI.
sleske

7

Thử:

$ ls -b

để xem tên tệp có các ký tự không thể in được.


Tại sao các downvote? Theo dõi , điều này nghe có vẻ như là một gợi ý rất tốt.
Ilmari Karonen

6

Không cần phải sử dụng perl ở đây, nhưng điều này sẽ hoạt động:

perl -e 'unlink "-"'

hoặc để xem bất kỳ lỗi nào ở trên có thể là:

perl -e 'unlink "-" or die "Err: $!"'

Phương pháp này có ưu điểm là không có ký tự đặc biệt nào phải lo lắng (ngoài các vấn đề trích dẫn chuỗi).
Kevin Reid

3

Tôi đã có may mắn khi sử dụng Nautilus của Gnome để xóa các tệp có tên xấu. Bạn đang chạy một máy chủ X? Tôi chắc chắn các trình duyệt tập tin khác cũng sẽ làm việc.


3

Nếu

rm -- -

không hoạt động, tên tệp không "chỉ là dấu gạch nối". Nếu không có tệp nào khác có dấu gạch nối trong đó, bạn có thể thử

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

1

Cho đến nay tôi nhận được "Không có tệp hoặc thư mục như vậy" cho mọi phương thức được đăng cho đến nay:

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

Có vẻ như tôi đã có phiên bản rm 7.4. Tôi sẽ thử nâng cấp và thử lại các đề xuất này. Cảm ơn mọi người đã giúp đỡ.


1
Tôi đoán rằng không có tệp hoặc thư mục như vậy và có lẽ tên tệp cũng chứa một số ký tự vô hình. (và bạn có thể nhận được thông báo lỗi tương tự trong perl với 'unlink "-" hoặc chết "Err: $!"'). Hãy thử "ls -b" để xem tên tệp thực sự là gì.
runrig

1

Tôi rất thích sử dụng dired chế độ trong emacs cho loại điều này - chỉ cần "mở" thư mục trong emacs. Bạn có thể dễ dàng chọn các tập tin và đánh dấu chúng để xóa.

Một poster khác đề nghị sử dụng chỉ huy nửa đêm; Đây là ý tưởng khá giống nhau, nhưng nếu bạn đã là người dùng emacs thì có lẽ thuận tiện hơn.


0

Có thể làm rm -f '-'việc cho tôi trong cygwin

Đối với vấn đề đó, rm -dường như cũng làm việc trên mũ đỏ.


trong Ubuntu: ~ / jj $ rm -rf '-' ~ / jj $ ls -

rm -làm việc cho tôi quá
uzsolt

1
Tại sao -r? Yêu cầu xóa đệ quy nếu bạn không cần, điều này luôn nguy hiểm trong trường hợp có lỗi.
Hans-Peter Störr

@hstoerr, điểm tốt. chỉ hợi. tay gõ nhanh hơn não. chỉnh sửa phản hồi bây giờ, cảm ơn.
Lucas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.