Dos dir mask, want "*.xxx" and not "*.xxxzz"

15,212

Solution 1

With the DIR command, when you specify a mask containing an extension of exactly three characters, you will get matches of files that contain extensions with three or more characters, so long as the first three characters match the extension you originally specified.

I have no idea why it works this way, but at least the behavior is consistent nearly everywhere in the Windows API where you can specify a file search pattern. I can only assume it has something to do with support for long file extensions (i.e., file names that don't comply with the old DOS 8.3 rule).

But, you can get around the behavior in two ways:

  1. A mask that specifies a file extension with one, two, or more than three characters will return only files with extensions of exactly the specified length.

    So, for example, dir /s/b "*.xx" will give you only files with the extension .xx, and dir /s/b "*.xxxzz" will give you only files with the extension .xxxzz.

  2. You can use the question mark wildcard character, instead of the asterisk. Asterisks mean "replaced by zero or more characters", while question marks mean an exact substitution of the question mark with a single character.

Solution 2

I suspect you're running into a problem because of the way Windows (older versions, at least) generated a short 8.3 filename to improve compatibility with old programs. You can probably confirm this by doing dir /x *.xxx in the directory where your *.xxxzz files exist.

I'm not sure if there's a way around it from the limited Windows command line tools. There should probably have been a switch on the dir command to force consideration only of long filenames, but I don't see one.

You may be able to solve your problem by disabling short filenames on that volume, if you're sure you don't need them for any ancient software you're running.

I haven't tried that myself, so maybe the short names already generated will continue to exist after you follow those instructions. If so, you might be able to fix it by copying the tree you're working with to a new location.

Solution 3

The fact is that unless the system has been set up to not generate 8.3 names, every file or directory with a long filename will also have an 8.3 alias. At least one - with some of the warped constructs in use in later editions, there many be many aliases.

Academically, since it's a matter of opinion (and hence outside of SO's bailiwick) it could be argued that your alternative command processor is not producing the correct results since it apparently ignores the short filename. Which is "correct" is debatable - what suits in one application may not in another. The easiest and most logical way of course is to have an option - but the chances of the major player in the debate incorporating such a facility at this stage amount to well,Buckley's

Here's a routine that may suit. It's not bullet-proof as it will have problems with some "poison characters" (those with special meaning for the standard command-processor cmd.exe(A windows application that emulates and enhances many of the facilities available in DOS, and normally, though technically-incorrectly, called "DOS" by the politically-incorrect for the sake of brevity.))

@ECHO Off
SETLOCAL
SET "mask=%~1"
IF "%mask:~-4,1%"=="." ECHO(%mask:~-3%|FINDSTR /L "* ." >NUL&IF ERRORLEVEL 1 (
 FOR /f %%a IN ('dir /s/b "%mask%"') DO IF /i "%%~xa"=="%%~sxa" ECHO(%%a
 GOTO :EOF 
)
dir /s/b "%mask%"

GOTO :EOF
Share:
15,212
Mark Robbins
Author by

Mark Robbins

The Art of Technology Independent developer of web technology and .NET applications with over 20 years programming experience

Updated on June 30, 2022

Comments

  • Mark Robbins
    Mark Robbins almost 2 years

    In my directories, I have file names like *.xxx and also *.xxxzz

    When I do dir /s/b "*.xxx" I get *.xxxzz files in my list. I do NOT get these results in a "Take Command" console, but I do in a cmd console.

    How do I get cmd to give me only *.xxx files?