Làm cách nào để xóa một tệp có tên bắt đầu bằng từ - - (dấu gạch ngang hay dấu gạch ngang)?


349

Làm cách nào để xóa một tệp có tên tệp bắt đầu bằng dấu gạch ngang (dấu gạch nối hoặc dấu trừ) -? Tôi đang vào một máy chủ OSX từ xa và tôi có tệp này trong thư mục của mình:

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

Làm thế nào trên thế giới tôi có thể xóa --helpkhỏi CLI? Vấn đề này là một cái gì đó mà tôi gặp trong các hình thức khác nhau, các tệp này rất dễ tạo, nhưng khó để thoát khỏi.

Tôi đã thử sử dụng dấu gạch chéo ngược

rm \-\-help

Tôi đã thử báo giá

rm "--help"

Làm cách nào để ngăn ký tự dấu trừ (dấu gạch ngang hoặc dấu gạch ngang) được hiểu là một tùy chọn?


1
Sẽ rất tuyệt nếu câu hỏi này được đổi tên thành "Cách xóa tệp có tên bắt đầu bằng -".
Sandy

@Sandy Đồng ý; Tôi thường không thích thay đổi ý nghĩa của một câu hỏi, nhưng trong trường hợp này, câu trả lời được chấp nhận là cụ thể cho vấn đề này
Michael Mrozek

33
tôi thấy có một chút mỉa mai mà rm --helpthực sự giải thích làm thế nào để xóa tên tập tin bắt đầu bằng a -. câu hỏi hay.
lesmana

1
@ jw013 Đôi khi sự giúp đỡ dễ dàng cho người dùng có kinh nghiệm hiểu, nhưng quá sức và khó hiểu đối với người mới.
iconoclast

1
Tôi đã gặp vấn đề này trên một hệ thống sử dụng rm từ BusyBox. Mọi thứ đều tối thiểu, bao gồm cả sự giúp đỡ, vì vậy rm --help không cung cấp bất kỳ manh mối nào.
dslake

Câu trả lời:


497

Sử dụng "-" để làm cho rm dừng phân tích các tùy chọn dòng lệnh, như thế này:

rm -- --help

1
Tôi biết đó là một thứ rất đơn giản như thế này ...
Bryan Rehbein

2
Do tất cả các phiên bản của rmlệnh hỗ trợ --đối số?
Keith Thompson

3
@KeithThndry - là một tính năng của hầu hết các công cụ GNU, do đó, nó sẽ không hoạt động trên hầu hết các Unix không phải GNU ("không phải Linux") (ví dụ: các biến thể BSD hoặc một số hệ thống nhúng)
dtech

1
CẢM ƠN! Điều đó đã cứu ngày của tôi. Và tất nhiên nó hoạt động trên BSD (OSX) và với các lệnh khác!
raskhadafi

8
@dtech, getopt () và --trước GNU (SysIII, 1980) và là tiêu chuẩn / POSIX. Các tiện ích tiêu chuẩn ngoại trừ một vài ngoại lệ (như echo) hiểu --. YMMV cho các lệnh khác nếu chúng không sử dụng API getopt () để phân tích các tùy chọn.
Stéphane Chazelas

214

Hoặc bạn có thể làm

rm ./--help

7
Không phải là vấn đề nhưng điều này có vẻ "đúng đắn" nhất.
James M.

2
Đây là một trong những mà tôi nhớ. Sử dụng "rm - --help" là điều tôi luôn phải tìm kiếm.
user603

25
Phương pháp này luôn hoạt động ngay cả đối với các lệnh không được xử lý --đặc biệt.
jw013

Và nó cũng hoạt động để tránh sự đối xử đặc biệt bằng một số lệnh cho các loại khác (bên cạnh các tùy chọn) của các đối số được đặt tên đặc biệt như các -tiện ích văn bản hoặc cd, foo=barcủa awk...
Stéphane Chazelas

1
Điều này hoạt động khi một tập tin bắt đầu với một dấu gạch ngang duy nhất, nơi rm -- <filename>không.
StockB

37

Sử dụng findđể làm điều đó:

find . -name '--help' -delete

Và đây là một phương pháp tốt bởi vì nếu bạn có nhiều hơn thì một vài tệp như thế này bạn có thể xóa, bạn có thể lấy danh sách xem trước của các tệp bằng cách chạy find mà không có -deletetùy chọn trước, và sau đó nếu danh sách các tệp trông ổn chỉ cần chạy nó lại với -delete.

Trên thực tế, bạn tránh rmviệc ủng hộ find(đặc biệt là xem trước trước) là một thói quen tốt sẽ giúp bạn tránh những sai lầm với rm *điều đó chắc chắn sẽ cắn bạn một ngày nào đó.

Tuy nhiên, lưu ý rằng tìm kiếm đó sẽ lặp lại qua tất cả các thư mục con của bạn, vì vậy bạn có thể muốn chạy nó với một ràng buộc độ sâu thư mục con như thế này:

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

mà giới hạn tìm thấy trong thư mục hiện tại.


Có thể, bạn cần đưa ra findmột danh sách các tập tin / thư mục để xem xét. Vì vậy find . -name.... -delete-maxdepthcũng không phải là lựa chọn tiêu chuẩn.
Stéphane Chazelas

21

Câu trả lời của Vegar Nilsen và edfuh là rất tốt và là giải pháp thích hợp cho một vấn đề như thế này.

Tôi muốn thêm một câu trả lời chung cho câu hỏi này cho phép bạn xóa bất kỳ tệp nào có tên tệp khó. Đầu tiên, số inode của nó được lấy bằng cách sử dụng ls -ihoặc một số dạng statvà sau đó tệp được loại bỏ bằng cách tìm kiếm các tệp trong thư mục hiện tại bằng số inode và thực hiện rmlệnh trên tệp với số inode phù hợp

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

Vì số inode là duy nhất trong mỗi hệ thống tệp, bạn có thể xóa bất kỳ tệp nào bằng cách sử dụng tệp này; unicode hoặc sử dụng các ký tự thoát. Việc loại ra rất khó chịu vì vậy tôi khuyên bạn nên thêm dòng

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

vào .inputrctập tin của bạn nếu bạn đang sử dụng bash. Điều này cho phép bạn chuyển qua danh sách các lần hoàn thành có thể ( để biết thêm thông tin ).


5
Cách này có hai vấn đề: 1) không sử dụng -exec rm khi bạn có thể sử dụng -delete; 2) có được inode và sử dụng quá mức không cần thiết khi bạn chỉ có thể sử dụng:find -name '--help' -delete
aculich

Tôi không nghĩ rằng nó sẽ làm việc. Nó đi qua tất cả các tệp trong thư mục hiện tại và tất cả các thư mục con của nó, và sau tất cả những gì nó vẫn gọi rm --help, mà vẫn không xóa tệp. Chỉ cần sử dụng rm ./--help(hoặc rm -i *.
Keith Thompson

1
@KeithThndry findtiền tố đường dẫn đối số dòng lệnh cho tất cả các tệp, vì vậy nó sẽ chạy rm ./--helprm ./sub/dirs/--help. Để sửa lỗi thứ hai, người ta sẽ phải thêm -maxdepth 1, nhưng tất cả điều này về cơ bản là áp dụng giải pháp của @ edfuh theo cách vòng vo hơn, cách phức tạp hơn và -deletean toàn hơn bất kỳ cách nào -exec rm.
jw013

1
Một vấn đề nữa với lệnh này là phải có khoảng cách giữa {}\;nếu không nó sẽ không hoạt động.
Eugene S

các nút có thể là duy nhất nhưng có thể có một số mục thư mục có cùng một nút. Chúng được gọi là liên kết cứng. Và chúng chỉ là duy nhất cho mỗi hệ thống tệp, vì vậy bạn cần sử dụng -xdev. Điều đó sẽ không giúp bạn chạy nó ls -i --help.
Stéphane Chazelas

11

Một giải pháp tàn bạo:

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

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

8

Linux Hướng dẫn tạo một tệp có dấu gạch ngang và dấu cách, sau đó xóa tệp đó.

HÃY CẨN THẬN! Đừng vô tình chạy một rm -rf /lệnh xóa tầng tương tự.

Nếu tập tin của bạn, bạn đang cố gắng để loại bỏ bao gồm dấu sao hoặc dấu gạch chéo, không vô tình bơm một .hoặc /*hoặc *hoặc một số ký tự đại diện khác mà có thể thác xóa hệ điều hành của bạn.

Tạo một tệp có tên "--yo yo"

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

Đầu tiên, tìm nó với find:

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

Đảm bảo lệnh find CHỈ tìm thấy MỘT tệp bạn muốn xóa:

Sau đó chuyển tùy chọn -delete để tìm, xóa chúng:

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

Aaaannd nó đã biến mất.


2

Midnight Commander ( mc) là dễ nhất, chỉ vào nó và nhấn F8;)


3
OP muốn một giải pháp dòng lệnh (CLI).
Francesco Turco

1
Chỉ huy nửa đêm là một giải pháp CLI. Chỉ cần sử dụng trình quản lý gói của bạn để cài đặt nó. (Nó thậm chí hoạt động trên ssh ...) vi.wikipedia.org/wiki/
REnight_Commander

6
Làm thế nào là apt-get install mc || yum install mc; mc các phím mũi tên khác nhau và F8 dễ dàng hơn rm ./--help?
Josh

3
@daviewales: Midnight Commander được bắt đầu từ dòng lệnh và nó chạy trong thiết bị đầu cuối, nhưng tất cả các hành động bàn phím trong Midnight Commander không phải từ CLI (Giao diện dòng lệnh) - chúng là từ Giao diện chỉ huy Midnight. - Thông thường, các tiện ích dòng lệnh có thể được chạy trong một tập lệnh (một ngoại lệ là lịch sử dòng lệnh bash)
Peter.O

1

đây là một giải pháp mà tôi đã sử dụng trước khi tìm thấy chủ đề này.
sử dụng vimđể 'chỉnh sửa' thư mục:

vim .

sau đó (trong vim) chọn tệp của bạn, nhấn del và xác nhận xóa.
khi bạn hoàn thành việc bỏ vim với:q


0

Bạn đã thử thêm tên thư mục làm tiền tố:

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

Sử dụng thư mục làm tiền tố của tệp nói chung giúp tránh việc giải thích sai ký tự "trừ" làm tùy chọn lệnh của hàm phân tích cú pháp.


1
Tôi tin rằng điều này đã được đề cập trong một câu trả lời trước đó .
Kusalananda

-3

Nếu bạn muốn đổi tên tệp -.bar, (mv sẽ không hoạt động), hãy thử điều này:

cat >foo.bar <-.bar

trước khi sử dụng lệnh:

rm -- -.bar

Bạn sẽ có thể kiểm tra nội dung của tệp gốc trong foo.bar


4
Tạo một bản sao của tệp không phải là một giải pháp rất hiệu quả để đổi tên nó.
jw013

1
Bạn có thể sử dụng vidir; nhưng điều đó có lẽ chỉ là (hoặc thậm chí nhiều hơn) không hiệu quả - và nguy hiểm hơn nhiều.
Stephen Menasian
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.