在cmd.exe下,如何防止“del *.tmp”删除*.tmpl文件?

在cmd.exe下,如何防止“del *.tmp”删除*.tmpl文件?

在 Windows 10 cmd.exe 下,该命令del *.tmp可能会默默删除类似的文件project.tmpl

是否有某种选项、解决方法、注册表项或仪式祭祀可以防止这种情况发生?

令人难以置信的是:在我的计算机上,C: 盘在 2020 年被 Windows 10 安装程序格式化:

演示

(法语错误信息意味着文件未找到)。

答案1

一份文件可能有简短的 DOS 8.3 名称和所有内部命令从 DOS 时代开始,出于兼容性原因,长文件名和短文件名都可以使用1,因此可能会意外匹配具有长扩展名的文件。有许多类似的问题:

最好使用 PowerShell,因为短名称不再匹配。cmddir中的必须匹配短名称,以免破坏旧程序。PowerShell 没有这个限制。只需运行Remove-Item *.tmp或其任何别名rm *.tmp,例如del *.tmp

在 cmd 中你必须findstr像这样过滤

for /F "delims=" %f in ('dir /B ^| findstr /I /E ".tmp"') do @del "%f"

(在批处理文件中%f替换)%%f

还有许多其他解决方案,例如forfiles(因为这不是 cmd 的内部命令),您可以在如何使“dir”和“copy”命令对“*.xyz”进行操作但不对“*.xyz~”进行操作?


不过禁用 8.3 名称生成并删除所有简称。事实上,自 Windows 8 和 Windows Server 2012 以来新格式化的卷将默认禁用 8.3 名称生成出于性能原因。这也有助于避免出现以下情况:WinXP dir 命令:3 和 4 个字符扩展名相同吗?

事实上,当您格式化新的数据卷时,Windows Server 的最新版本甚至没有启用 8.3 命名。

https://docs.microsoft.com/en-us/archive/blogs/josebda/windows-server-2012-file-server-tip-disable-8-3-naming-and-strip-those-short-names-too

如果您的驱动器仍启用了 8.3 名称生成,则运行以下命令在驱动器 C 上禁用它:

fsutil 8dot3name set C: 1

或运行fsutil 8dot3name set 1以在所有卷上禁用它

也可以在注册表中设置。对应的键是HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation。和注册表项的值fsutil如下

  • 0:为系统上的所有卷启用 8dot3 名称创建。
  • 1:禁用系统上所有卷的 8dot3 名称创建。
  • 2:根据每个卷设置 8dot3 名称创建。
  • 3:禁用除系统卷之外的所有卷的 8dot3 名称创建。

如果有名称,也可以使用以下方法删除fsutil 8dot3name strip

注意fsutil必须以管理员权限运行


1旧命令使用旧命令列出文件FindFirstFile匹配长名称和短名称的 API。请参阅为什么要FindFirstFile找到短名称?. 新代码应使用FindFirstFileEx而不是避免

答案2

发生这种情况的原因是 Windows 保留了与以下文件名的兼容性:操作系统,文件名扩展名限制为 3 个字符。为了方便过渡,Windows 95引入了兼容模式,其中每个文件都有一个“8.3”别名,也称为文件的“短名称”:除了 之外project.tmpl,同一个文件也可以作为 访问PROJEC~1.TMP。您可以在目录列表中使用 看到这些短名称dir /x。通配符模式与*.tmp此替代名称匹配(文件名不区分大小写)。微软记录了这一点dir;它也适用于其他命令,包括del

我可以在我的公司 Windows 10 机器上重现您观察到的行为(不是从以前的 Windows 10 升级而来的)。我拥有本地管理员权限,但没有域管理员权限,并且不允许我运行fsutil 8dot3name query c:Error: Access is denied.)。

如果您控制生成临时文件的系统部分,一个可靠的解决方法是为它们指定一个非 3 个(或 0 个)字符长的扩展名。*.tm否则*.temp将无法匹配具有不同扩展名的文件名的 8.3 别名。或者,将这些临时文件放在单独的目录中,并在您想要删除它们时删除整个目录。

答案3

除了在phuclv 的回答,你可以使用不太知名但非常酷的档案命令:

FORFILES /M *.tmp /C "CMD /C ECHO @path && DEL @path"

“搜索掩码”参数(/M)与 8.3 名称不匹配,因此.tmp.tmpl是两个不同的扩展名,无需任何额外的过滤。搜索掩码也不区分大小写。

例如:

C:\TEMP>echo a > del_test_1.tmp

C:\TEMP>echo a > del_test_2.TMP

C:\TEMP>echo a > del_test_3.tmpl

C:\TEMP>dir *.tmp
 Volume in drive C is Windows
 Volume Serial Number is B0F0-812B

 Directory of C:\TEMP

04/28/2021  11:46 AM                 4 del_test_1.tmp
04/28/2021  11:48 AM                 4 del_test_2.TMP
04/28/2021  11:48 AM                 4 del_test_3.tmpl
               3 File(s)             12 bytes
               0 Dir(s)  179,312,234,496 bytes free

C:\TEMP>FORFILES /M *.tmp /C "CMD /C ECHO @path && DEL @path"

"C:\TEMP\del_test_1.tmp"
"C:\TEMP\del_test_2.TMP"

C:\TEMP>dir *.tmp
 Volume in drive C is Windows
 Volume Serial Number is B0F0-812B

 Directory of C:\TEMP

04/28/2021  11:48 AM                 4 del_test_3.tmpl
               1 File(s)              4 bytes
               0 Dir(s)  179,310,305,280 bytes free

答案4

您需要一个文件for loop来避免第三个文件在“ .tmp”后带有附加字符也被删除......

for /t tokens^=* %i in ('where .:*.tmp')do echo\ del "%~i"

where 命令将仅返回.end具有.tmp(仅)的文件...

您还可以尝试/R递归:

for /t tokens^=* %i in ('where/r "D:\MyProject\Folder" *.tmp')do echo\ del "%~i"

  • 我无法解释发生在你身上的这件事的原因,但它也发生在我身上......

  • 现在我知道了...@phuclv 在他的回答中解释道...请考虑他的回答

> reg query "HKLM\System\CurrentControlSet\Control\FileSystem" /v "NtfsDisable8dot3NameCreation"

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\FileSystem
    NtfsDisable8dot3NameCreation    REG_DWORD    0x0

在此处输入图片描述

在此处输入图片描述


  • 使用For /fwithwhere保存文件*.tmp*

在此处输入图片描述

  • 我也不知道该如何解释为什么这个活动没有与@spikey_richie 一起举行......

相关内容