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
一个文件可能有短的 DOS 8.3 名称,出于兼容性原因,来自 DOS 时代的所有内部命令也可以使用长名称和短名称1,因此可能会意外匹配具有长扩展名的文件。类似的问题还有很多:
最好使用 PowerShell,因为不再匹配短名称。
dir
在 cmd 中必须匹配短名称,以免破坏遗留程序。PowerShell 没有这个限制。只需运行Remove-Item *.tmp
或其任何别名rm *.tmp
,例如del *.tmp
在 cmd 你必须
findstr
像这样过滤(在批处理文件中替换
%f
为)%%f
还有许多其他解决方案,例如
forfiles
(因为这不是 cmd 的内部命令),您可以在How can I get the "dir" and "copy" commands to operation on "*.xyz" but not "*.xyz~ “?但是,禁用 8.3 名称生成并删除所有短名称会更好。事实上,从 Windows 8 和 Windows Server 2012开始,出于性能原因,新格式化的卷将默认禁用 8.3 名称生成。这也有助于避免这样的情况:WinXP dir command: 3 和 4 char extensions are the same?
如果您的驱动器仍然启用了 8.3 名称生成,则运行以下命令在驱动器 C 上禁用它:
或运行
fsutil 8dot3name set 1
以在所有卷上禁用它该设置也可以在注册表中设置。对应的键是
HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation
。和注册表项的值fsutil
是这样的如果名称在那里,它也可以删除
fsutil 8dot3name strip
注意
fsutil
必须以管理员权限运行1旧命令使用
FindFirstFile
匹配长名称和短名称的旧 API 列出其文件。请参阅为什么会FindFirstFile
找到短名称?. 应该使用新代码FindFirstFileEx
来避免这种情况发生这种情况的原因是 Windows 保留了与MS-DOS文件名的兼容性,其中文件名被限制为 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 文件名别名。或者,将这些临时文件放在单独的目录中,并在您想要删除它们时删除整个目录。除了phuclv 的答案中提供的基于 CMD 的解决方案之外,您还可以使用 not-well-known-but-very-cool FORFILES命令:
“搜索掩码”参数 (
/M
) 与 8.3 名称不匹配,因此.tmp和.tmpl是两个不同的扩展名,没有任何额外的过滤。搜索掩码也不区分大小写。例如:
您需要一个
for loop
来避免在“”之后添加其他字符的第 3 个文件.tmp
也被删除...where 命令将仅返回
.end
带有.tmp
(仅)...的文件您也可以尝试
/R
递归:我无法解释发生在你身上的这件事的原因,但它也发生在我身上……现在我知道了……@phuclv 在他的回答中解释了……请考虑他的回答
For /f
withwhere
保存文件*.tmp*
我也不知道如何解释为什么@spikey_richie 不会发生这个事件......