The Computer Oracle

Under cmd.exe, how can "del *.tmp" be prevented from deleting *.tmpl files?

--------------------------------------------------
Rise to the top 3% as a developer or hire one of them at Toptal: https://topt.al/25cXVn
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Switch On Looping

--

Chapters
00:00 Under Cmd.Exe, How Can &Quot;Del *.Tmp&Quot; Be Prevented From Deleting *.Tmpl Files?
00:45 Accepted Answer Score 36
03:34 Answer 2 Score 9
05:22 Answer 3 Score 8
06:17 Answer 4 Score 4
07:25 Thank you

--

Full question
https://superuser.com/questions/1644682/...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#cmdexe

#avk47



ACCEPTED ANSWER

Score 36


A file may have short DOS 8.3 names and all internal commands from DOS era also work with both long and short name for compatibility reasons1 so a file with long extension may be accidentally matched. There are many similar questions:

It'd be better to use PowerShell because short names aren't matched anymore. dir in cmd must match the short names in order to not break legacy programs. PowerShell doesn't have that limitation. Just run Remove-Item *.tmp or any of its aliases like rm *.tmp, del *.tmp

In cmd you'll have to filter with findstr like this

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

(Replace %f with %%f in a batch file)

There are also many other solutions such as forfiles (as that's not a cmd's internal command) that you can find in How can I get the "dir" and "copy" commands to operate on "*.xyz" but not "*.xyz~"?


However it'll be even better to disable 8.3 name generation and remove all the short names. In fact since Windows 8 and Windows Server 2012 newly formatted volumes will have 8.3 name generation disabled by default for performance reasons. That'll also help avoid situations like this: WinXP dir command: 3 and 4 char extensions are the same?

In fact, recent versions of Windows Server don’t even enable 8.3 naming when you format new data volumes.

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

If your drive still has 8.3 name generation enabled then run the following command to disable it on drive C:

fsutil 8dot3name set C: 1

or run fsutil 8dot3name set 1 to disable it on all volumes

The setting can also be set in registry. The corresponding key is HKLM\System\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation. The value for the fsutil and the registry key is like this

  • 0: Enables 8dot3 name creation for all volumes on the system.
  • 1: Disables 8dot3 name creation for all volumes on the system.
  • 2: Sets 8dot3 name creation on a per volume basis.
  • 3: Disables 8dot3 name creation for all volumes except the system volume.

If the names are there it can also be removed with fsutil 8dot3name strip

Note that fsutil must be run with admin privileges


1Old commands list their files using the old FindFirstFile API which matches both long and short names. See Why does FindFirstFile find short names?. New code should use FindFirstFileEx instead to avoid that




ANSWER 2

Score 9


The reason this happens is that Windows has retained compatibility with file names from MS-DOS, where file names were limited to a 3-character extension. To facilitate the transition, Windows 95 introduced a compatibility mode where every file has an “8.3” alias, also known as the file's “short name”: in addition to project.tmpl, the same file is also accessible as PROJEC~1.TMP. You can see these short names in directory listings with dir /x. The wildcard pattern *.tmp matches this alternative name (file names are case-insensitive). Microsoft documents this for dir; it applies to other commands as well, including del.

I can reproduce the behavior you've observed on my corporate Windows 10 machine (not upgraded from a previous Windows 10). I have local admin privileges, but not domain admin, and I'm not allowed to run fsutil 8dot3name query c: (Error: Access is denied.).

If you control the part of the system that's producing the temporary files, a robust workaround is to give them an extension that is anything but 3 (or 0) characters long. *.tm or *.temp would not match 8.3 aliases of file names with a different extension. Alternatively, put those temporary files in a separate directory and just remove the whole directory when you want to delete them.




ANSWER 3

Score 8


In addition to the CMD-based solution provided in phuclv's answer, you can use the not-well-known-but-very-cool FORFILES command:

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

The "search mask" parameter (/M) does not match on the 8.3 names, hence .tmp and .tmpl are two different extensions without any additional filtering. The search mask is also case-insensitive.

For example:

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



ANSWER 4

Score 4


You need one for loop to avoid some 3rd file with additional characters after ".tmp" to be deleted too...

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

The where command will return only files .end with .tmp (only)...

You can also try /Recursive:

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

  • I can't explain the reason for this event that happened to you, but it happens to me too...

  • Now I know... @phuclv explained in his answer ... plz, consider his answer

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

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

enter image description here

enter image description here


  • Using For /fwith whereto keep files *.tmp*

enter image description here

  • I also don't know how to explain why this event doesn't happen with @spikey_richie...