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

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

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

ls -lq
total 2
-rw-r--r--. 1 mbyx7ag2 zk01 0 May  1  2014 ???E@X?p@8?@

我曾无数次尝试杀死这个东西,但到目前为止都无济于事。每当我收到错误,因为该文件不存在,尽管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

有趣的是,那里的 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

不起作用。

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

答案1

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

  File: `\001\360\265E@X\342p@8\b@'

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

$ 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

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

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

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

rm ^A*

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

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

rm -rf ./CorrectDirectory        ### Be careful this will erase ANYthing.

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

答案2

正如您知道名称中的实际字符一样,您只需为文件名构建正确的转义序列,如中所述http://tldp.org/LDP/abs/html/escapingsection.html

  1. 创建

    $ echo test > $'\001\360\265E@X\342p@8\b@'
    $ stat $'\001\360\265E@X\342p@8\b@'
      Fichier : ''$'\001\360\265''E@X'$'\342''p@8'$'\b''@'
       Taille : 5           Blocs : 8          Blocs d'E/S : 4096       fichier
    Périphérique : 10302h/66306d    Inœud : 6948089     Liens : 1
    Accès : (0640/-rw-r-----)  UID : ( 1001/username)   GID : (                                 1003/jrousseau)
    Accès : 2018-06-20 11:40:44.333208199 +0200
    Modif. : 2018-06-20 11:40:47.589113454 +0200
    Changt : 2018-06-20 11:40:47.589113454 +0200
      Créé : -
    
  2. 删除

    $ rm -i $'\001\360\265E@X\342p@8\b@'
    rm : supprimer fichier ''$'\001\360\265''E@X'$'\342''p@8'$'\b''@' ? y
    $
    

答案3

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

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

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

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

答案4

  • 列出目录中的所有文件并将名称保存到 file_list
  • 编辑 file_list 删除除要删除的文件之外的所有文件

for f in \`cat file_list\` 
do
   /bin/rm  -i  $f   # option i to be extra safe 
done 

相关内容