如何在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
让我想起一个同事创建名为*的文件的时间。这个故事结局不好。
大卫·赫弗南

rm您使用的是哪个版本(rm --version)?rm -与GNU coreutils 8.5兼容。
Lekensteyn 2011年

2
另一个变体:rm ./-
CVn

Answers:


60

这曾经发布在Unix的Usenet常见问题解答中-我看到它在GNU Core Utility常见问题解答中。至少有五种不同的方法,但是效果很好:

$ rm ./-

如果文件名包含无法键入的字符,请使用:

$ rm -i *

-i标志要求确认是否应删除每个文件。


1
或者RM -i - “ - ”如果您正在寻找包含一个破折号文件,也许一些空间或别的什么东西。
汉斯·彼得·斯特尔

1
rm -i *也为我工作。谢谢wallyk!
jgrundstad 2011年

39

删除名称以开头的文件-是一个常见问题解答,但看来您遇到了其他问题。

您在问题中提到的解决方案中:

rm -- -

那应该工作。

rm "-"

这与没什么不同rm -。引号被外壳剥离,该rm命令仅将单个连字符作为参数。引号对于转义外壳元字符很有用;连字符对rm,而不是外壳。

rm "\-"

引号引起来的是反斜杠,因此这会尝试删除名称由两个字符(反斜杠和连字符)组成的文件。

rm \-

就像 rm "-",相当于rm -

碰巧的是,至少使用GNU coreutils版本的rmrm -实际上会删除(或尝试删除)名称仅由连字符组成的文件。如果您的文件具有该名称,则该名称现在将消失。我得出的结论是,您的文件名称看起来像连字符。

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是Unicode“ EN DASH”字符0x2013的3字节UTF-8表示形式的表示形式。我想知道您是否不小心从网页中复制并粘贴了它。
基思·汤普森

7
没有rm -i *工作吗?好像它会和perl脚本做同样的事情。
user606723,2011年

2
我猜它源于指向wget的网页。无论如何,再次感谢您的彻底解决方案!照顾自己。
jgrundstad 2011年

5
perl -e'unlink grep {print“删除$ _?”; <STDIN> =〜/ y / i} glob“ *”'
Randal Schwartz

6
@RandalSchwartz:令人印象深刻的简洁(使我的大脑有点受伤)-但我想要/^y/i而不是/y/i。毕竟,俄罗斯用户可能会输入“ Nyet”。
基思·汤普森

19

如果您想要更安全的东西...

尝试结合使用ls和find(这适用于您有权删除的任何文件)

“ -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看不到有任何方法可以做到这一点。
斯蒂芬·P

哦,是的,在这种情况下。更像是一个小费。
Sirex

13

rm ./-一试。

-是开始一个标志参数标志。如果您使用参数以外的其他参数作为参数开头-,在这种情况下/,它将假定它是文件名。这就是你想要的。

而且,由于file./file是相同的文件,它会针对该文件命名为-通过./-


8
与其输入30个字符,不如解释为什么/有助于正确解析,可能会更有用
Ivo Flipse

@gcb感谢您提出的修改。我在上面添加了代码标记,因此更容易阅读。
slhck 2011年

7

不像大多数其他答案那样令人讨厌,但是我将启动实例mc,午夜指挥官,然后选择并删除文件。


+1巧妙地避免了该问题-甚至无需求助于GUI程序。
sleske 2012年


6

并不是说必须在这里使用perl,但这应该可以工作:

perl -e 'unlink "-"'

或查看上述任何错误可能是:

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

此方法的优点是,无需担心特殊字符(字符串引用问题除外)。
凯文·里德

3

我很幸运使用GNOME的Nautilus删除了名字错误的文件。您正在运行X服务器吗?我确定其他文件浏览器也可以使用。


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.

看来我有rm版本7.4。我将尝试升级并重新尝试这些建议。感谢大家的帮助。


1
我猜测没有这样的文件或目录,也许文件名还包含一些不可见的字符。(并且您可能在perl中使用“取消链接“-”或死于“ Err:$!””得到同样的错误消息))。尝试使用“ ls -b”查看真正的文件名。
runrig 2011年

1

我很喜欢使用 dired在emacs mode来做这种事情-只是“打开” emacs中的目录。您可以轻松选择文件并将其标记为删除。

另一个海报建议使用午夜指挥官;这几乎是相同的想法,但是如果您已经是emacs用户,则可能更方便。


0

应该可以rm -f '-'在Cygwin中为我工作

就此而言,rm -似乎也可以戴上红色帽子。


在Ubuntu中:〜/ jj $ rm -rf'-'〜/ jj $ ls –

rm -也为我工作。
uzsolt 2011年

1
为什么-r?如果不需要,则请求递归删除总是很危险,以防误解。
汉斯·彼得·斯特尔

@hstoerr,好点。只是习惯。手打字比大脑快。现在编辑回复,谢谢。
卢卡斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.