FreeBSD:目录名为^ C(真的!)-如何删除?


127

我打错了字:

$ history
169 9:34    la /usr/local/etc/
170 9:35    sudo mkdir ^C
171 9:36    sudo mkdir /usr/local/etc/dnsmasq.d

现在,我有一个名为^ C(ctrl + C)的文件!当我使用时,ls我只会看到一个问号(可能是由于语言环境所致?)

% ls -al
total 60
drwxr-xr-x  2 root   wheel    512 Jan 21 09:35 ?        <- this one
drwxr-xr-x  5 admin  wheel    512 Jan 21 16:24 .
drwxr-xr-x  3 root   wheel    512 Jan 20 14:29 ..
-rw-r--r--  1 admin  nobody  1114 Jan 20 19:10 .cshrc
-rw-------  1 admin  wheel   6002 Jan 21 15:27 .history
-rw-r--r--  1 admin  nobody   182 Jan 20 14:29 .login
-rw-r--r--  1 admin  nobody    91 Jan 20 14:29 .login_conf
-rw-------  1 admin  nobody   301 Jan 20 14:29 .mail_aliases
-rw-r--r--  1 admin  nobody   271 Jan 20 19:04 .mailrc
-rw-r--r--  1 admin  nobody   726 Jan 20 19:05 .profile
-rw-------  1 admin  nobody   212 Jan 20 14:29 .rhosts
-rw-r--r--  1 admin  nobody   911 Jan 20 19:06 .shrc
drwx------  2 admin  nobody   512 Jan 20 15:05 .ssh
drwxr-xr-x  2 admin  wheel    512 Jan 20 19:08 bin

% ls -i
3611537 ?   3611534 bin

我要删除此文件。我尝试mv使用制表符补全时向我显示:

% mv
^C/  bin/

显然我无法输入^ C:-/如何删除此文件?


11
dsw没有进入POSIX 是非常糟糕的。
Mark Plotnick

12
@MarkPlotnick:太糟糕了,原始 dsw文档没有放入POSIX。
Matteo Italia

4
我不认为您将其命名为ctrl + C,而是以映射到该键盘快捷方式(即ETX(ASCII 3))的ASCII字符命名。您的控制台字体没有针对该字符的字形,因此它使用通用替换字形“?”。
jiggunjer

5
emacs -nw -f dired提供目录导航器。确认后,<kbd> D </ kbd>删除光标下方的文件。
托尔比约恩Ravn的安德森

9
@MatteoItalia它在文件名和其他太差控制字符愚蠢的 想法把它做成POSIX ...

Answers:


188

^Vctrl+ v)用作下一次按键的转义序列,插入关联的值,而不是执行通常会关联的任何操作。

利用此^V^Cctrl+ vctrl+ c)应该可以在终端中输入您困难的文件名。


41
这可能是OP首先打错字的方式。V和C在键盘上彼此相邻。
Stig Hemmer

14
或者他们试图在bsd终端上使用Windows剪贴板。
Joel Coel

2
@JoelCoel习惯永不消亡!
Mafii

1
有趣的是,^V^C不是在岩组线编辑工作; 带引号的插入小部件(在页面中搜索^V)不会显式插入中断字符。Jakob的答案(使用printf)可能是在shell参数中提供控制字符的更可移植的方式。
英里

@StigHemmer:还可能发生的情况是,您在命令中间按Ctrl-C,然后忘记此操作并稍后将其复制粘贴。
Mehrdad

89

您也可以通过inode删除文件:

$ ls -i1
290742 foo
293246 ^C
$ find . -inum 293246 -delete

不管你做什么,偏偏,不要把-delete之前-inum

$ touch foo bar baz quux
$ find . -name '*u*' -delete
$ ls
bar baz foo
$ find . -delete -name 'b*'
find: `./baz': No such file or directory
find: `./bar': No such file or directory
$ ls
$ 

恭喜,您刚刚删除了所有文件。find参数顺序很重要


2
为什么不放在-delete前面-inum呢?这是否只是一种预防措施,以防您过早按Enter或参数的顺序实际上影响结果?
detuur

10
@detuur:顺序会影响结果。参见编辑。
主教

37
-delete在运行命令之前,请勿-delete检查命令是否已找到所需内容。
卡兹(Kaz)

2
@Kaz在命令中心添加-delete将
无济于事

9
@Kaz使用-print代替-delete进行了很好的测试。
马克·兰瑟姆

32

另一种选择是使用rm -ri ./*; rm会在删除任何文件和目录之前询问您,因此您只需要答复y“错误”文件以及n所有其他文件。

实际上,根据您的情况,您甚至可以减少执行所需的回复次数rm -ri ./?,因为您的“不良”文件只有一个字符长。


8
select f in ?; do rm -i "$f"; break; done具有的所有优点-i,而不必no为导致不良后果而做出的回答或对要保留的错误回答是的痛苦。
主教

6
对于OP,它是目录,而不是文件。 rmdir ?/将删除所有空的单字符目录,并抱怨其他目录非空。
彼得·科德斯

2
@bishop:哇,我什至不知道它的select存在,非常干净!
Matteo Italia

@PeterCordes:糟糕,我没有注意到我们在谈论目录。我在示例中添加了-r(而且./-总是很容易忘记),因为不幸的rmdir是不支持该-i标志。我仍然认为,在这种情况下,最好的方法是结合主教的意见和您的评论。
Matteo Italia

1
@MatteoItalia select仅存在于某些shell中,这可能就是为什么您没有遇到它的原因-旨在可移植的脚本和解决方案可以避免它,因此我们不太可能在野外看到它。
mtraceur

23

一种选择是使用以外的其他内容查找文件名ls。如果您知道它是由逐字Ctrl+ 产生的C,则可以找到使用控制字符表产生的ASCII 字符,或使用更友好的界面(如Python提供的界面)产生的ASCII字符:

>>> import os
>>> os.listdir('.')
['\x03', ...]

另一种选择是ls使用eg 来查看输出的十六进制转储hexdump

然后,您可以使用以下bash命令删除文件:

rmdir "$(printf '\x03')"

(仅当您要打印的字符位于IFS变量中时,才需要双引号,例如\x20\x0A,但是除非您希望外壳程序执行字段拆分等,否则通常使用引号替换命令)。


2
另外cat -v(加man ascii),可以帮助的第一部分。
Matteo Italia

13
...或者os.rmdir('\x03')直接在Python Shell中使用。
moooeeeep

15

在这种情况下,通常很容易想出与相关文件匹配的通配符模式

在您的情况下,这很简单?(将所有文件名精确地匹配一个字符)。

只需检查它是否确实符合您的要求即可:

ls -ld ?

然后删除目录:

rmdir ?

您还可以将其与制表符完成功能结合使用。您可以输入

rmdir ?

然后按Tab键,例如在bash中它将被替换

rmdir ^C/

然后您可以按Enter键,它会做您想要的。


11

您可以使用Midnight Commander(mc)删除文件-只需使用向上/向下按钮进行选择,然后按F8。

当文件名由于编码而具有奇怪的字符时,我偶尔会这样做。


4
或几乎任何其他文件管理器。
Stig Hemmer

@StigHemmer当然,在显示某些文件名时,某些文件比其他文件做得更好。答案很可能可以解释为什么与少数其他选择相比,MC是最佳选择。我不知道,因为我从未使用过它。
can-ned_food

7

另一种方法:用于stat获取目录名称的转义表示:

$ stat *|grep File:
  File: ‘\003’

现在您知道了文件名的表示形式,因此可以使用printf以下名称按名称删除文件:

$ rmdir -v "$(printf '\003')"
rmdir: removing directory, ‘\003’

或者,如果您使用的是bash,则可以避免printf

$ rmdir -v $'\003'
rmdir: removing directory, ‘\003’

顺便说一句,如果外壳是bash,$'\x03'则比调用printf更简单。FreeBSD sh也是如此,它通过POSIX shell扩展并具有一些不错的功能。
Netch

@Netch关于bash的优点$'...',但是我通常会避免从八进制到十六进制的无用转换。例如,如果文件被命名'\111'(在stat输出中)怎么办?您还会使用删除它$'\x49'吗?更好地利用相同的顺序stat给你:在OP的情况下,rmdir $'\003'
罗斯兰

6

对我有用的解决方案是:

rm ./[Tab][Tab][Tab]...

循环浏览可用文件,直到找到要删除的文件为止。

但是您确实需要在shell中具有必要的设置才能起作用。


^ C确实在制表符序列中处于早期位置,因此为您+1。
joshudson

5

最简单的方法是将所有内容移动到临时目录,然后再移动rm -r DIRNAME


7
对您来说,这真的比接受的答案容易吗?
小鸡

2
@chicks:这实际上不是一个糟糕的答案。我已经看到^ V ^ C不起作用,所以有人可能会卡住。
joshudson

本身并没有错,但是与更直接的解决方案相比,这似乎是很多额外的工作。也许我被Linux宠坏了,但是^v多年来我一直为我工作。
小鸡

6
@chicks ^V需要一些特定的知识,而移动文件和删除父目录可以从基础知识中获得。
Kondybas

5
Ctrl + V可能会模棱两可,具体取决于您的实际工作环境……某些终端仿真器可能会将其解释为粘贴。如果粘贴缓冲区包含您不想删除的内容的名称-以及换行符,则可能是您遇到了问题。
rackandboneman '18

1

如果它是唯一的空目录(或者您不关心删除其他空目录),请使用rmdir */。您将收到rmdir有关无法删除非空目录的错误消息,但这很好。GNU rmdir支持--ignore-fail-on-non-empty,或者可以2>/dev/null

尾部/使glob仅匹配目录名称。

您可以使用提前检查当前目录下存在哪些空目录
find -maxdepth 1 -type d -empty -ls。(并且您可以根据需要将更-ls改为-delete)。

您可以使用更特定的全局表达式,例如rmdir [^A-Za-z0-9._]/匹配以非字母数字或下划线文件名开头的目录。我也包括在内.,但是glob表达式无论如何都不.正常。


正如其他人指出的那样,您可以将其限制为具有以下字符的单字符名称?rmdir ?/

rmdir没有-i方法可以rm做的选择,大概是因为空目录通常没有价值,只能重新创建。


1
您想知道要重新创建的目录,并rmdir可以告诉您是否将-v选项传递给它(至少在GNU中)。
Ruslan '18

@Ruslan:如果您不再需要其他过时的目录,则不会,删除它们将是一个好处。你可以寻找空目录,与find -maxdepth 1 -type d -empty -ls
彼得·科德斯

-1

在做任何冒险之前,请先尝试以下方法:

rmdir -- ^C

通常,-是一个分隔符,告诉命令不会出现任何-o选项,但是它也允许怪异的字符不被解释为其他字符。

另一个用法示例是 whois -r -- "-r OBJECT-RIPE"

(-r是成熟的快捷方式,但在成熟的who也是参数)

如果初次尝试不起作用,则可以尝试 rmdir -- "^C"

但是在我的csh shell上我不需要任何东西,只是rmdir ^C已经对我有用。


1
在csh中键入rmdir 后跟<ctrl> C可以工作吗?真?!我希望它的行为有所不同,即中止rmdir命令并将您返回命令行。
Mausy5043

的确会。请参阅有关如何在命令行上输入^ C字符的公认答案。
Ale
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.