删除名称以“?”开头的文件 在命令行中

Smi*_*lia 7 command-line debian nemo delete

我在 Debian stable、Cinnamon DE 下运行,我有一些文件想用命令行删除(现在我用 Nemo 删除这些文件)。

例如,这些.txt文件以“?”开头。在 shell 和 Nemo 中,这个 '?' 被回车代替:

$@debian: ls
ssolveIncpUL46pK  ?ssolveIncpUL46pK.txt
Run Code Online (Sandbox Code Playgroud)

尼莫

我试过:

 rm ?ss*
 rm \?ss*
 rm \ ss*
Run Code Online (Sandbox Code Playgroud)

Siv*_*iva 27

删除此类文件的适当方法是使用文件的inode值。

使用以下命令获取inode

 ls -li 

 12582925 -rw-r--r--  1 root root   646 May 23 02:19 ?ssolveIncpUL46pK.txt
Run Code Online (Sandbox Code Playgroud)

入围结果的第一个字段是 inode 值。

然后使用find命令删除文件wrt inode。

find . -inum 12582925 -exec rm -i {} \;
Run Code Online (Sandbox Code Playgroud)

  • 这实际上是不安全的。多个文件可以具有相同的 inode(使用硬链接)。因此,不是只删除其中带有明显问号的文件,而是删除该文件以及该目录和任何后代子目录中具有相同 inode 编号的所有其他文件。 (4认同)

Kus*_*nda 18

字符不是问号。该ls实用程序将用?. 还不清楚不可打印字符是否真的是文件名中的第一个字符,或者在此之前是否可能有一个或几个空格。

你想删除这两个文件,你可以匹配“坏部分”,*然后更紧密地指定可见文件名的其余部分:

rm -i ./*ssolve*
Run Code Online (Sandbox Code Playgroud)

这将首先将给定的模式扩展到与其匹配的所有文件名,然后rm将它们删除。更具体地讲,如果有文件,您指定的文件名较长的一部分希望删除匹配空头格局,如上述

rm -i ./*ssolveIncpUL46pK*
Run Code Online (Sandbox Code Playgroud)

这是假设您与要删除的文件位于同一目录中。

使其在实际删除任何内容之前要求确认的-i选项rm

  • 下一个问题是:当 `?ss*` 不匹配时,为什么 `*ssolve*` 匹配它? (8认同)
  • @StéphaneChazelas 因为`?` 与文件名的“坏部分”不够匹配。它可能与多字节字符有关?或者可能只是在不可打印字符之前有一个空格。在这种事上你比我好。 (4认同)

ImH*_*ere 12

不建议使用 a*来删除文件。它可以比你喜欢的更匹配。

在 Debian 中,ls(来自 GNU)命令能够以引用形式打印文件的值[ 1 ]

$ ls -Q
"\nssolve"  "\n\nssolve"  "y"  "z"
Run Code Online (Sandbox Code Playgroud)

或者,更好的是,列出带有引用名称和 inode 的文件:

$ ls -iQ
26738692 "\nssolve"  26738737 "\n\nssolve"  26738785 "y"  26738786 "z" 
Run Code Online (Sandbox Code Playgroud)

然后,使用带有 inode 编号的 rm 以确保仅删除正确的文件:

$ find . -xdev -inum 26738737 -exec rm -i {} \;
Run Code Online (Sandbox Code Playgroud)

对 find 的调用仅限于一个文件系统 ( -xdev) 以避免匹配其他文件系统上具有相同 inode 编号的文件。另请注意,rm使用-i(交互式)选项调用它,因此它会在命令行中询问是否应删除每个文件。


[ 1 ]请注意,这并不能解决视觉上容易混淆的字符的问题,例如西里尔文?($'\U430') 和拉丁文a($'\U61'),它们看起来完全相同,但实际上并不相同。为了更好地查看文件名使用的字节,我们需要使用十六进制查看器;

$ touch ? a é $'e\U301' $'\U301'e
$ ls
a  ?e  e?  é  ?              # what you "see" here depends on your system.

$ printf '<%s>' * | od -An -c
   <   a   >   < 314 201   e   >   <   e 314 201   >   < 303 251
   >   < 320 260   >
Run Code Online (Sandbox Code Playgroud)