ฉันจะลบไฟล์ใน Linux ที่ชื่อดูเหมือนว่าเป็นเครื่องหมายยัติภังค์เท่านั้นเช่นเดียวกับ“ -”


33

ฉันได้พยายาม

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

ยิง Perl ให้

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

...และ...

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

ความช่วยเหลือใด ๆ จะได้รับการชื่นชมมากคนฉลาด


ด้วยความอยากรู้อยากเห็นมันมาที่นี่ได้อย่างไร
Petey B

2
มันเป็นผลมาจาก wget ที่สร้างมาไม่ดี: "wget ​​-q -O - someserver.org/s/ip "

53
เตือนฉันถึงเวลาที่เพื่อนร่วมงานสร้างไฟล์ชื่อ * เรื่องนี้ยังไม่จบดี
David Heffernan

rmคุณใช้เวอร์ชันอะไร( rm --version) rm -ทำงานได้ดีกับ GNU coreutils 8.5
Lekensteyn

2
ตัวแปรอื่น:rm ./-
CVn

คำตอบ:


60

ใช้วิธีนี้จะได้รับการโพสต์ใน Usenet คำถามที่พบบ่อยสำหรับ Unix-ฉันเห็นมันอยู่ในGNU คอ Utility คำถามที่พบบ่อย มีอย่างน้อยห้าวิธีที่ต่างกัน แต่วิธีนี้ใช้ได้ดี:

$ rm ./-

หากชื่อไฟล์มีอักขระที่ไม่สามารถพิมพ์ได้ให้ใช้:

$ rm -i *

การ-iตั้งค่าสถานะจะขอการยืนยันสำหรับแต่ละไฟล์ว่าควรลบออกหรือไม่


1
หรือ rm -i - ' - ' หากคุณกำลังมองหาไฟล์ที่มีเส้นประและอาจมีช่องว่างหรืออะไรก็ตาม
Hans-Peter Störr

1
rm -i * ก็ใช้ได้กับฉันเช่นกัน ขอบคุณ wallyk!
jgrundstad

39

การลบไฟล์ที่ชื่อขึ้นต้นด้วย-คำถามที่พบบ่อย แต่ดูเหมือนว่าคุณมีปัญหาอื่น

จากคำตอบที่คุณพูดถึงในคำถาม:

rm -- -

ว่าควรจะทำงาน

rm "-"

rm -นั่นคือไม่แตกต่างจาก เครื่องหมายคำพูดถูกถอดออกโดยเชลล์และrmคำสั่งจะเห็นเครื่องหมายขีดกลางเดียวเป็นอาร์กิวเมนต์ เครื่องหมายอัญประกาศมีประโยชน์สำหรับการหลบหลีกเชลล์ตัวอักษร ยัติภังค์นั้นพิเศษสำหรับrmไม่ใช่ที่เปลือก

rm "\-"

เครื่องหมายคำพูดยกเว้นเครื่องหมายแบ็กสแลชดังนั้นจะพยายามลบไฟล์ที่ชื่อประกอบด้วยอักขระสองตัวแบ็กสแลชและยัติภังค์

rm \-

นี้เป็นเช่นเดียวเทียบเท่ากับrm "-"rm -

มันเกิดขึ้นอย่างน้อยกับ GNU coreutils รุ่นrm, rm -จริงลบ (หรือพยายามที่จะลบ) ไฟล์ที่มีชื่อประกอบด้วยเพียงยัติภังค์ หากไฟล์ของคุณมีชื่อนั้นไฟล์จะหายไปในตอนนี้ ฉันสรุปได้ว่าไฟล์ของคุณมีชื่อที่ดูเหมือนยัติภังค์เท่านั้น

ls | cat -A

ควรให้ความเห็นเกี่ยวกับสิ่งที่เรียกว่าจริง ๆ

ต่อไปนี้เป็นสคริปต์ Perl ที่ฉันเพิ่งโยนเข้าหากันซึ่งจะทำให้คุณพร้อมสำหรับแต่ละไฟล์ในไดเรกทอรีปัจจุบันและถามว่าจะลบมันหรือไม่ เสนอโดยไม่มีการรับประกัน แต่ฉันได้ทำการทดสอบสั้น ๆ

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

แก้ไข : ทางออกที่ซับซ้อนน้อยกว่า: หากชื่อไฟล์เป็นเพียงหนึ่งตัวอักษรแล้วrm ?ควรลบออก (พร้อมกับไฟล์อื่น ๆ )


13
M-bM-^@M-^Sเป็นการแสดงผลของการเป็นตัวแทน UTF-8 ขนาด 3 ไบต์ของอักขระ Unicode "EN DASH", 0x2013 ฉันสงสัยว่าคุณตั้งใจคัดลอกและวางจากหน้าเว็บหรือไม่
Keith Thompson

7
ไม่rm -i *ได้ทำงาน? ดูเหมือนว่ามันจะทำเช่นเดียวกับสคริปต์ Perl
user606723

2
ฉันเดาว่ามันมาจากหน้าเว็บที่ฉันชี้ไปที่ wget ไม่ว่าในกรณีใด ๆ ขอขอบคุณอีกครั้งสำหรับการแก้ปัญหาอย่างละเอียด! ดูแล.
jgrundstad

5
perl -e 'unlink grep {พิมพ์ "ลบ $ _?"; <STDIN> = ~ / y / i} glob "*" '
Randal Schwartz

6
@RandalSchwartz: ประทับใจสั้น (และทำให้สมองของฉันเจ็บบิต) - แต่ฉันต้องการมากกว่า/^y/i /y/iท้ายที่สุดผู้ใช้ชาวรัสเซียอาจพิมพ์ "Nyet"
Keith Thompson

19

หากคุณต้องการสิ่งที่ปลอดภัยกว่า ...

ลองใช้การรวมกันของ ls และค้นหา (สิ่งนี้ใช้ได้กับไฟล์ใด ๆ ที่คุณมีสิทธิ์ลบออก)

พารามิเตอร์ '-i' จะให้หมายเลขไอโหนดสำหรับแต่ละรายการไดเรกทอรี ls -li

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

เมื่อคุณมีหมายเลขไอโหนด ...

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

2
+1 เนื่องจากนี่เป็นคำตอบทั่วไปที่ยอดเยี่ยมสำหรับปัญหาเหล่านี้ โดยวิธีการที่ไม่จำเป็นต้องใช้ -exec rm ในการค้นหาล่าสุดเพียงใช้ -delete
Sirex

2
@Sirex - ฉันคิดว่าจุดประสงค์-exec rm -i {}คือการ-iพร้อมท์สำหรับการลบ ฉันกำลังดูman findและไม่เห็นวิธีการทำเช่นนั้น
สตีเฟ่นพี

โอ้ใช่ในกรณีนี้ เป็นเคล็ดลับเพิ่มเติม
Sirex

13

ให้rm ./-ลอง

นี่-คือการตั้งค่าสถานะเพื่อเริ่มต้นอาร์กิวเมนต์การตั้งค่าสถานะ หากคุณเริ่มการโต้แย้งด้วยสิ่งใด ๆ ยกเว้น a -ในกรณีนี้/มันจะถือว่าเป็นชื่อไฟล์ สิ่งที่คุณต้องการ

และตั้งแต่fileและ./fileเป็นแฟ้มเดียวกันก็จะกำหนดเป้าหมายไฟล์ชื่อผ่านทาง-./-


8
แทนที่จะพิมพ์ 30 ตัวอักษรบางทีมันอาจจะมีประโยชน์มากกว่าที่จะอธิบายว่าทำไม / ช่วยในการแยกวิเคราะห์อย่างถูกต้อง
Ivo Flipse

@gcb ขอบคุณสำหรับการแก้ไขที่เสนอ ฉันเพิ่มรหัสมาร์กอัปลงในนั้นดังนั้นมันจะง่ายต่อการอ่าน
slhck

7

ไม่เหมือนคำตอบอื่น ๆ ที่น่าเกินบรรยาย แต่ฉันจะแสดงตัวอย่างmcผู้บัญชาการเที่ยงคืนและเลือกและลบไฟล์


+1 สำหรับการแก้ปัญหาอย่างชาญฉลาด - และไม่ต้องใช้โปรแกรม GUI
sleske

7

ลอง:

$ ls -b

เพื่อดูว่าชื่อไฟล์มีอักขระที่ไม่สามารถพิมพ์ได้หรือไม่


ทำไมต้องลงคะแนน รับการติดตามนี้ดูเหมือนว่าคำแนะนำที่ดีมาก
Ilmari Karonen

6

ไม่ใช่ว่ามันควรจะจำเป็นที่จะต้องใช้ Perl ที่นี่ แต่มันก็ใช้ได้ดี:

perl -e 'unlink "-"'

หรือเพื่อดูว่ามีข้อผิดพลาดใด ๆ ข้างต้นอาจเป็น:

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

วิธีนี้มีข้อได้เปรียบที่ไม่มีอักขระพิเศษที่ต้องกังวล (นอกเหนือจากปัญหาการอ้างอิงสตริง)
เควินเรด

3

ฉันโชคดีที่ใช้ Nautilus ของ GNOME เพื่อลบไฟล์ที่มีชื่อไม่ดี คุณใช้ X-server อยู่หรือไม่? ฉันแน่ใจว่าเบราว์เซอร์ไฟล์อื่นจะใช้งานได้เช่นกัน


3

ถ้า

rm -- -

ไม่ทำงานชื่อไฟล์ไม่ใช่ "แค่เครื่องหมายขีดคั่น" หากไม่มีไฟล์อื่นที่มีเครื่องหมายขีดคั่นอยู่คุณสามารถลองใช้

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

1

จนถึงตอนนี้ฉันได้รับ "ไม่มีไฟล์หรือไดเรกทอรี" สำหรับทุกวิธีที่โพสต์:

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

ดูเหมือนว่าฉันจะได้รับเวอร์ชัน 7.4 ฉันจะลองอัปเกรดและลองคำแนะนำเหล่านี้อีกครั้ง ขอบคุณทุกคนที่ช่วย


1
ฉันคาดเดาว่าไม่มีไฟล์หรือไดเรกทอรีดังกล่าวและบางทีชื่อไฟล์อาจมีอักขระที่มองไม่เห็นด้วย (และคุณอาจได้รับข้อความแสดงข้อผิดพลาดเดียวกันในภาษา Perl ด้วย 'unlink "-" หรือตาย "Err: $!"') ลอง "ls -b" เพื่อดูว่าชื่อไฟล์จริงคืออะไร
runrig

1

ฉันชอบใช้diredโหมดใน emacs มากสำหรับสิ่งนี้ - เพียงแค่ "เปิด" ไดเรกทอรีใน emacs คุณสามารถเลือกไฟล์และทำเครื่องหมายเพื่อลบได้อย่างง่ายดาย

โปสเตอร์อื่นแนะนำให้ใช้ผู้บัญชาการเที่ยงคืน นี่เป็นแนวคิดเดียวกัน แต่ถ้าคุณเป็นผู้ใช้ emacs อยู่แล้วมันอาจจะสะดวกกว่า


0

ควรจะสามารถrm -f '-'ทำงานให้ฉันใน cygwin

สำหรับเรื่องนั้นrm -ดูเหมือนว่าจะทำงานกับหมวกสีแดง


ใน Ubuntu: ~ / jj $ rm -rf '-' ~ / jj $ ls -

rm -ทำงานให้ฉันด้วย
uzsolt

1
ทำไมต้อง -r การร้องขอการลบแบบเรียกซ้ำหากคุณไม่ต้องการมันจะเป็นอันตรายเสมอในกรณีที่การสะกดผิด
Hans-Peter Störr

@hstoerr จุดดี เพียงแค่กระต่าย มือพิมพ์เร็วกว่าสมอง ตอบกลับการแก้ไขทันทีขอบคุณ
ลูคัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.