答案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 命名。
如果您的驱动器仍启用了 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 /f
withwhere
保存文件*.tmp*
我也不知道该如何解释为什么这个活动没有与@spikey_richie 一起举行......