删除包含非打印字符的文件

The*_*dus 5 bash

我遇到过一个意外创建的文件,并且文件名非常糟糕。的输出ls -lq

ls -lq
total 2
-rw-r--r--. 1 mbyx7ag2 zk01 0 May  1  2014 ???E@X?p@8?@
Run Code Online (Sandbox Code Playgroud)

我曾无数次尝试杀死这个东西,但到目前为止都无济于事。每当我收到错误,因为该文件不存在,尽管ls在那里显示它并且能够使用stat它:

stat ^A?E\@X?p\@8^H\@ 
  File: `\001\360\265E@X\342p@8\b@'
  Size: 0           Blocks: 3          IO Block: 32768  regular empty file
Device: 1ah/26d Inode: 5239755888  Links: 1
Access: (0644/-rw-r--r--)  Uid: (231058/mbyx7ag2)   Gid: (10027/    zk01)
Access: 2014-05-01 15:47:28.638919596 +0100
Modify: 2014-05-01 15:47:28.638919596 +0100
Change: 2014-05-01 15:47:28.638919596 +0100
Run Code Online (Sandbox Code Playgroud)

有趣的是,那里的 stat 命令是制表符补全的结果,看起来与其他地方使用的名称完全不同。

我尝试过这些问题中的想法:

如何删除没有名称的文件

有没有办法找到只包含非打印字符的文件?

我还尝试了从文件名中删除非打印字符 - 北极地区超级计算中心(在“删除非打印字符”下)的两种方法。

令人担忧的是,使用 inode 的所谓“万无一失”的技巧如下:

ls -i
5239755888 ???E@X?p@8?@
find . -inum 5239755888 -delete
find: cannot delete `./\001\360\265E@X\342p@8\b@': No such file or directory
Run Code Online (Sandbox Code Playgroud)

不起作用。

有谁知道我可以用来删除这个文件的其他技巧吗?

小智 5

您打印的 stat 似乎是正确的文件名(存储在目录中)。

  File: `\001\360\265E@X\342p@8\b@'
Run Code Online (Sandbox Code Playgroud)

您可以使用以下命令重新构建名称(以字节为单位):

$ printf '%b' '\001\360\265E@X\342p@8\b@' | od -An -tx1
soh   p   5   E   @   X   b   p   @   8  bs   @
 01  f0  b5  45  40  58  e2  70  40  38  08  40
Run Code Online (Sandbox Code Playgroud)

如您所见,该字符串以控制字符 (soh) 或十六进制 0x01(八进制 \001)开头。这既有坏的影响(文件难以擦除),也有好的影响(目录中不太可能存在同名文件)。

将所有(其他)文件移出目录后(为了安全起见)。

您可以尝试通过键入rm、然后键入文件的第一个字符 (soh) 和星号 ( *) 来删除文件(与执行操作时类似erase a*)。输入 的技巧0x01是同时输入 Ctrl and v,释放它们并输入Ctrland A(不需要shift)。^A光标位置上应出现。然后键入一个星号*。您应该在控制台上看到这一行:

rm ^A*
Run Code Online (Sandbox Code Playgroud)

然后按回车键,如果有效,文件应该就消失了。

如果这不起作用(尝试几次),总有核武器解决方案。移动并删除所有其他文件,更改到父目录,然后执行以下操作:

rm -rf ./CorrectDirectory        ### Be careful this will erase ANYthing.
Run Code Online (Sandbox Code Playgroud)

整个目录(包括文件)将消失。


mic*_*has 0

一种简单的方法是使用像mc. 这样,您只需指向该文件并要求删除它,而无需考虑转义字符。

在您的情况下,stat可以看到您的文件,但rm不能。这很奇怪。这可能确实是您的文件系统的问题。(尝试fsck。)

为了进行更多调试,您还可以尝试使用strace来检查为什么一个命令能够看到该文件,而另一个命令却不能。

另一个想法是rm -r删除整个目录。(可能在备份里面的所有重要文件之后。)