header image

如何删除有特殊字符的文件或目录

最近在NAS上遇到了一个头痛的问题,由于NAS的Shell功能有限,SSH连过去之后虽然能显示中文,但是却无法输入,复制粘贴也不行。于是上网到处找,没想到中文搜索竟一无所获,最终找到了英文的,在这里搬运翻译一下。

虽说我的情况是删除中文文件,但其实这些情况适用于任何特殊字符(比如还有>(输出重定向)、*(通配符)、-(命令选项)、$(变量引用)、(空格,分隔参数和选项)等),也可以举一反三用在其他操作上。

把文件名放到引号中

这可以说是最基本的方法了,Shell中引号表示字符串,所以有些字符放到引号中就不具有本来在Shell命令中的功能了。单引号'或者双引号"都可以,但注意要配对。例如删除名为my file的文件:

rm "my file"

用反斜杠转义

用反斜杠\转义字符相信编写过程序的都不陌生,有的特殊字符是可以用反斜杠转义的,转义之后就失去在Shell命令中的功能了。实际上如果经常用Tab来自动完成命令的话就会发现,自动完成的就是用反斜杠来转义的。例如删除名为[my file]的文件:

rm \[my\ file\]

在文件名前加上./

./表示当前目录,有的字符如果出现在空格后面就有特殊含义(比如-表示命令选项),但加上./之后就不是了。比如删除名为-my-file的文件:

rm ./-my-file

在文件名前加上--

--表示结束命令选项,在其之后的字符都被视为参数。当然,--两边要加上空格,而且只对文件开头的是-的有效,其他特殊字符还是要用其他办法。比如删除名为-my-file的文件:

rm -- -my-file

用inode编号删除

上面的方法只能针对某些特殊字符,对于我在本文开头说到的情况无能为力,但是我们还有最终解决方案。关于什么是inode就不详细说了,反正这里只要知道在一个文件系统上每个文件或目录都有一个inode编号。这个编号可以通过ls-i选项来查看,为了看得清楚,我们再加上选项-1来让一项结果占一行。

li -i1

比如我这里有三个特殊文件名的文件file-file$file的结果如下:

63184461  file
63181495 -file
63184295 $file

文件名前面的数字就是inode编号了。

可是rm并不支持用inode来删除,怎么办呢,这里就要请出另一个命令了,这就是find。这是个查找文件的命令,它有个选项-inum可以指定inode编号,还有个选项-delete可以直接删除文件。

find . -inum 63181495 -delete

.表示在当前目录查找,-inum 63181495就是查找inode编号为63181495的文件,-delete就是将找到的文件删除。

-delete选项只能删除文件和空目录,要删除有文件的目录怎么办呢,这个时候就要另一个选项出场了——-exec,表示将查找到的文件放到其后的命令中。在命令中{}会用查找到的文件代替。

find . -inum 63181495 -exec rm -ri {} \;

rm的选项-r表示递归删除目录和里面的内容,-i表示删除每一个项之前都弹出提示询问以免误删。

于是,目录被我快乐地删除掉了。

赞赏

微信赞赏支付宝赞赏

1 comment

reply

your email will keep secret. (* required).

you can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> .