Windows wildcards with files having more than 3 characters extensions

Solution 1:

You're not using MS-DOS; it did not even allow file extensions longer than 3 characters. You're using the Windows command line – the cmd.exe shell, specifically.

But Windows indeed tries hard to remain compatible with programs from that era. So, up until Windows 8 (or something like that), all files with longer extensions have an alias that has the extension truncated, along with the name itself.

If you run dir /x, you'll likely see that each file has a "short name" assigned to it, which is limited to 8+3 characters, just like in MS-DOS and 16-bit Windows.

These names are there in case the user wanted to, let's say, upgrade to Windows 95 and still access their files through programs originally written for Windows 3.1 – so running a 16-bit program wouldn't crash, but would merely show C:\PROGRA~1 and C:\MYDOCU~1\CALENDAR.TXT in place of C:\Program Files and C:\My Documents\Calendar.txt.

(And yes, some people did actually use old 16-bit software even in Windows XP/Vista days... I'm pretty sure Windows 8 turn off the "short names" by default, however. This might be why @EBGreen isn't seeing the same 'problem'...)


Another thing to consider is that the old Windows shell, cmd.exe, has grown quite a few quirks and compatibility fixes in itself. For example, due to the way MS-DOS matched filenames, dir .txt meant the same as dir *.txt, even though it wasn't intentional. But people got used to the shorter syntax, and even though the Windows operating system itself doesn't treat .txt as a wildcard anymore, cmd.exe still accepts that syntax. (The dir command isn't a program on its own, but built into the shell.)

(Similarly, in the linked article, another wildcard quirk is described – Windows filenames can have no extension at all, but people are really used to typing *.*, therefore it means the same thing as * and the lone dot is ignored.)

Solution 2:

I can't tell you why it works that way. It is quite odd. What I can tell you is that Powershell (which you should have on the machine) works the way that you expect. In powershell:

PS I:\temp\test> ls


    Directory: I:\temp\test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        10/13/2014   9:29 AM          3 bar.txt
-a---        10/13/2014   9:29 AM          3 bar.txt2
-a---        10/13/2014   9:29 AM          3 foo.txt
-a---        10/13/2014   9:29 AM          3 foo.txt2

PS I:\temp\test> ls *.txt


    Directory: I:\temp\test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        10/13/2014   9:29 AM          3 bar.txt
-a---        10/13/2014   9:29 AM          3 foo.txt

Solution 3:

grawity correctly identified that the behavior stems from short file names. Filemasks are compared to both the long and short names.

The full rules for how wild cards are matched against file names is available in the "sourceMask" section of How does the Windows RENAME command interpret wildcards?

You can get your desired DIR result by piping to FINDSTR:

dir *.txt* | findstr /vrix "[0-9].*\.txt[^.][^.]*"