无法删除/移动文件名中带有特殊字符的文件


17

正如您在下面看到的,文件中有不常见的字符。

文件管理器截图

在终端或Dolphin中删除它们会返回错误:

无此文件或目录

ls -la在目录上运行给我以下输出:

-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ?2?.???љ?!?Gb??σ?[?F?
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 3l??#g?w????O?JKB7?co??քH??bT?NA???S???X?I?A?qC??M?I???
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??8??-?@,?Zp?[?bI????7^?ñ[?ڏ??z?O???ч??eEȰ?+??,OF??h

我在fsck另一个操作系统的分区上运行了一个命令,但没有任何改变。

如何删除这些文件?


1
您是否将系统设置为具有加密的主目录?
dobey

@多贝我没有。
karjedavpalaa

5
@豹你误会了。这本身并不表示文件系统已损坏,即使fsck 由某种类型的数据损坏引起的,fsck也不对此做任何事情。
zwol


1
我的文件名中包含无法识别的字符。重命名文件。然后可以将其删除。
狂欢1998年

Answers:


35

一种简单的方法是通过它们的inode删除这些文件。:)

使用ls -li目录与常见的字符显示每个文件的inode编号,例如,

$ ls -li
total 0
133370 -rw-r--r-- 1 malte malte 0 Dec 30 19:00 ?2?.???љ?!?Gb??σ?[?F?
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

接下来,使用该find实用程序,使用语法find <somepath> -inum <inode_number> -exec rm -i {} \;,按名称删除相应文件,如以下示例所示:

$ find . -inum 133370 -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
$ ls -li
total 0
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

-i选项rm是不是真的有必要,我只是说这让你从你并不想删除意外删除的文件。:)它导致rm要求确认要删除的每个文件。

如果要通过它们的inode删除多个文件,则可以将-o(意义)语法用于find

$ find .  \( -inum 133370 -o -inum 132584 \) -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
rm: remove regular empty file ‘./??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??’? y

您可以通过将括号内的表达式扩展为更多-o -inum <inode_number>表达式来添加更多的索引节点号。


4
怎么rm -ri .
布伦特·巴卡拉

工作正常:查找<somepath> -inum <inode_number> -exec rm -i {} \; “ -inum”,“ {}”和“ \”在命令中起什么作用?
karjedavpalaa

如何一次删除多个文件?另外,谢谢,您让我开心!
karjedavpalaa

2
但是,@ BrentBaccala rm -ri .不会通过inode删除文件。它只会简单地遍历整个工作目录并询问是否要删除每个文件-而且您必须非常专心地询问它要查找哪些文件,以免意外删除不需要的文件。我当然不想在我的主目录中使用此命令-它包含很多文件。;)
Malte Skoruppa

3
@karjedavpalaa(1)-inum讲述find寻找通过inode编号的文件。(2){}匹配由找到的文件grep。(3)\转义;符号,该符号终止传递给-exec选项的命令find。(4)我已经编辑了答案,以解释如何一次性删除多个文件。
Malte Skoruppa

13

重要的是要了解,这不是fsck可以帮助的“文件系统损坏” 。就文件系统而言,文件名可以是任何字节序列,只要没有单个字节具有值0x00(ASCII NUL,C字符串结尾标记)或0x2F(/目录分隔符)即可。(如果文件名确实以某种方式嵌入了00或2F字节,fsck则应予以解决。)

而是,您拥有的是应用程序软件(Dolphin,ls)认为包含在“语言环境” 中无法显示的字符的文件名,因此它将用占位符替换它们。您也不能键入这些字符,因此操作文件比较困难,但是只要您不键入,复制和粘贴名称就可以执行操作。例如,如果您直接从Dolphin内删除或重命名问题文件,那应该可以正常工作(我什至可以说,如果它不起作用,那是Dolphin中的错误)。

如果您需要通过外壳对它们进行某些操作(例如,如果它们归rootGUI程序所有,因此不能被GUI程序修改),则可以使用“全局”模式间接命名它们,这些模式将扩展为正确的顺序(s)个字节并传递。

现在,当然,您不希望偶然删除某些东西,因为您的glob模式匹配得太多,所以我的建议是使用Perl rename实用程序将每个文件名转换为十六进制编码:

$ rename '$_ = unpack("H*", $_)' *

这不会破坏任何信息-文件本身,也不会破坏之前在文件名中最初编码的任何含义。可以使用以下命令撤消特定文件的操作

$ rename '$_ = pack("H*", $_)' 696d706f7274616e742e646f63

注意:有两个rename来自不同来源的名为的程序。上述命令仅适用于源自Perl的命令。在Ubuntu中,您需要的是“重命名”软件包中的软件包,而不是“ util-linux”软件包中的软件包。 rename -h会区别:这就是您想要的...

$ rename -h
Usage:
    rename [ -h|-m|-V ] [ -v ] [ -n ] [ -f ] [ -e|-E perlexpr]*|perlexpr
    [ files ]
# ...

...这不是您想要的...

$ rename -h

Usage:
 rename [options] <expression> <replacement> <file>...
# ...

寻找的关键是“ perlexpr”。您可能具有旧版本的Perl重命名,它不能理解上面的所有选项,但是我显示的命令仍然可以使用。

编辑:在14.04 .5以下,所包含的perl脚本rename不支持-h开关。您可以通过检查手册页来确认自己是否正确,man rename在这种情况下,顶行将包含以下内容:

RENAME(1)Perl程序员参考指南RENAME(1)


重命名--version未知选项:版本
Elder Geek

@ElderGeek file $(which rename)打印什么?(请确保首先安装了file软件包。)
zwol18年

/usr/bin/rename: symbolic link to /etc/alternatives/renamefile默认情况下已安装)实际上,您必须追逐符号链接才能获得,/usr/bin/file-rename: a /usr/bin/perl -w script, ASCII text executable man rename它是更快的指示……
Geek Elder

@ElderGeek如果是perl脚本,则可能是“ Perl起源”的较旧版本,不支持--version;我建议的命令应该仍然有效。(我电脑上的/usr/share/doc/rename/changelog.gz运行Debian不稳定,表明它--version是在2013年的Perl重命名版本0.10中添加的。我很惊讶Ubuntu仍在发布比该版本更旧的版本,但该程序自2007年以来实际上并未更改其功能(所以很好)
。– zwol

啊! 这就解释了混乱。尽管有许多相反的说法,Debian不是Ubuntu。我不能说每个发行版,但是一些当前受支持的Ubuntu LTS(14.04)版本仍然没有。(尽管16.04确实有)
极客长老'18
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.