views:

179

answers:

2

i am trying to delete some files using a batch file.. (winxp)

my problem is when i delete using a wildcard.. it is matching the 8.3 name aswell as the long name.

eg: file list

file1.py
file1.pyc
file2.pycstlongname
file2.pycstlongnamec

if i do a

Del *.pyc

it deletes everything but file1.py

becuase if i do a dir /X all of teh 8.3 shortnames end with .PYC

+4  A: 

When you perform file management using wildcards from the command prompt, files with long extensions can be unexpectedly displayed, copied, or deleted.

You are right, it happens on my computer too, running fully-patched Windows XP SP3.

See the following Microsoft Knowledgebase Article for more information, and a registry change that will solve it. This one goes all the way back to Windows NT 4.0:

Article ID: 164351 - Last Review: November 1, 2006 - Revision: 1.1
Command Prompt's Treatment of Long File Extensions

http://support.microsoft.com/kb/164351

UPDATE: This behavior also occurs in a test C# application I wrote. The behavior is disturbing enough that I applied the registry fix to my computer, and it does work.

Robert Harvey
*sigh*.. yep.. that'd be right.. i'll test this later.i will not help me too much, because i want to distribute the .bat file.. and i wont be able to set the registry on every machine.
ShoeLace
You could always use the REG command in the .BAT file to test and adjust the key. It looks like it applies to the file system driver, so a reboot really would be required for it to take effect.
RBerteig
+4  A: 

Well, in your case you can probably use forfiles:

> forfiles /m *.pyc
"file1.pyc"

it does not adhere to cmd's wildcard expansion rules.

You can also enumerate all files and filter for extension afterwards:

> for %i in (*) do @if %~xi==.pyc @echo %i
file1.pyc

Both methods skip the files where only the .3 part of the extension matches.

So you can use either

forfiles /m *.pyc /c del @FILE

or

for %i in (*) do @if %~xi==.pyc @del "%i"

Admittedly, a little more complex than a simple del *.pyc, though.

ETA: Since someone was sceptical whether this would work, a little snippet from a cmd session on a Win XP SP 2 VM:

S:\Temp>for %i in (file1.py,file1.pyc,file2.pycstlongname,file2.pycstlongnamec) do @copy nul %i
        1 Datei(en) kopiert.
        1 Datei(en) kopiert.
        1 Datei(en) kopiert.
        1 Datei(en) kopiert.

S:\Temp>dir /b
file1.py
file1.pyc
file2.pycstlongname
file2.pycstlongnamec

S:\Temp>del *.pyc

S:\Temp>dir /b
file1.py

S:\Temp>del *

S:\Temp>for %i in (file1.py,file1.pyc,file2.pycstlongname,file2.pycstlongnamec) do @copy nul %i
        1 Datei(en) kopiert.
        1 Datei(en) kopiert.
        1 Datei(en) kopiert.
        1 Datei(en) kopiert.

S:\Temp>for %i in (*) do @if %~xi==.pyc @del "%i"

S:\Temp>dir /b
file1.py
file2.pycstlongname
file2.pycstlongnamec

Nevermind the German messages, I hope it shows that above method does in fact work.


To explain a bit why it works, we can take a look at the command:

for %i in (*) do @if %~xi==.pyc @del "%i"

The first part is trivial. for %i in (*) simply enumerates all files in the current directory. We then check for the extension; %~xi expands to the full extension (not 8.3 stuff), so running above line will cause the following commands to be run:

if .py == .pyc del "file1.py"
if .pyc == .pyc del "file1.pyc"
if .pycstlongname == .pyc del "file2.pycstlongname"
if .pycstlongnamec == .pyc del "file2.pycstlongnamec"

I hope it is obvious why this works better than the globbing done by cmd which includes 8.3 names. No wildcards here, nothing to do wrong.

The forfiles variant does work on my Win 7 and Vista machines here. I can only guess but I strongly suspect, forfiles does not implement the same wildcard matching rules as cmd. Since we are on Windows, every program expands wildcards for itself. This is not done by the shell, unlike on UNIX systems. How exactly programs do this differs sometimes and apparently it does here, too.

Needless to say that I consider forfiles's approach here a little more sensible as 8.3 names should die a horrible death sometime soon. Or at least I hope they do.

Joey
Windows Server 2008 only?
Robert Harvey
forfiles exists at least since Windows Vista, although I have seen it on some legacy XP machines as well so far. The for command dates back at least to NT 4.
Joey
Given the behavior of the OS using DEL from the command prompt AND FileInfo.Delete() from C# code, I am skeptical that this would actually work.
Robert Harvey
I elaborated a little and hopefully convinced you by now :-)
Joey
+1 for the explanation. I can see clearly why this would work.
Robert Harvey