The Friendly Coder

On software development and technology

Batch File Gotcha: Question Mark Wildcard

Todays batch file gotcha applies equally well to DOS commands in general, but if you think you understand how basic wildcard substitution is performed you may want to read on about this subtle gotcha…

Suppose you have a folder with the following 3 files in it:

file.txt
file1.txt
file2.txt

What do you suppose the output would be from the following command:

dir file?.txt

According to typical MS-DOS convention, you would likely expect to see two results: file1.txt and file2.txt. But as you may have suspected, that would be wrong. You actually get all three files as matches to your wildcard.

Why this happens is not altogether obvious, especially when you consider most sources will quote something similar to this MSDN snippet:

… the question mark matches any single character…

Some will even suggest, more explicitly, that it matches exactly one character because this is the typical behaviour if your query looks something more like fi?e.txt. So what exactly is going on here?

Undocumented Feature

It is an not-so-well-known fact that the question mark wildcard will match exactly one character only when the wildcard does not appear at the end of a file name. When the character appears at the end of the filename it will match either zero or one characters – which is why file.txt matches the pattern.

To make matters even worse, lets add a new text file fil.txt to our list and then try the following command:

dir fil??.txt

Once again all four files are matched to our wildcard. It is the same problem here, just with both question marks matching against non-existent characters in the ‘fil’ filename.

Workaround

So, what if we want to get a list of all the files with a number at the end (i.e.: file1.txt and file2.txt) and ignore the other files (i.e.: fil.txt and file.txt). How do we structure our command? From what I have found, there is no workaround for this using the typical MS-DOS wildcards. Please, if anyone out there can prove me wrong please add a comment with the solution.

The easiest work-around that will work on Windows 7, Vista or Windows XP SP2 or SP3 (or with the Windows Powershell utility installed) may work around the problem using the new Windows Powershell. For example, if you simply prepend a call to powershell to your command all will work as expected, as shown here:

Powershell DIR sample output

The wild card processing logic works correctly within the Powershell environment and you get the results you were likely expecting.

8 Responses to “Batch File Gotcha: Question Mark Wildcard”


  1. Squashman

    If you pipe the output to the findstr command you could do regular expression pattern matching.

  2. That is another good suggestion. For future reference, the syntax could look something like this: dir *.* | findstr file..txt


  3. christian

    This is an extremely valuable information but there is a typing error in “Undocumented Feature”: Instead of “dir file??.txt” (fil.txt not in list) there should be written “dir fil??.txt” which really lists all four files.

  4. Thanks for pointing out the typo. I’ve corrected it as you suggested.


  5. swhiteman

    dir file?.txt | find /v file.txt

    Obvs. still two steps, but you don’t need to “upgrade” to findstr.

    forfiles /m file?.txt

    forfiles uses more consistent wildcard behavior than dir (? matches only on a character, * matches on empty).

  6. Excellent suggestion. I like the first one in particular because it’s more universal since it doesn’t use any ‘modern’ DOS extensions. Conversely, from what I’ve read, forfiles is a relatively recent addition starting with Windows Vista.


  7. swhiteman

    Yeah, forfiles is officially post-XP but runs on XP no problem (it’s the one utility I immediately transplanted from 2003 into my XP \system32 when it came out).

    I know everyone has a breaking point when something seems just too foreign — me, if I can copy a single EXE from the contemporaneous server OS, I’m cool with it. But installing Powershell on XP would be too much for me to recommend: a client might not be so cool with the install, plus it’s such an obvious superset of the functionality you’re looking for. But YMMV!


  8. Jim

    Just learned today that using multiple question mark wildcards at the end of a filename can fetch a lot more than intended.

    Given the following folder contents:
    abc123456.txt
    abc1234561.txt
    abc12345611.txt
    abc123456111.txt
    abc1234561111.txt
    abc12345611111.txt
    abc123456111111.txt
    abc1234561111111.txt
    abc12345611111111.txt
    abc123456111111111.txt
    abc1234561111111111.txt

    I want to find the file named like ‘abc??????.txt’
    I varied the number of question marks and found that:

    dir /b /a-d abc12345?.txt hits on
    abc123456.txt

    dir /b /a-d abc1234??.txt hits on
    abc123456.txt

    dir /b /a-d abc123???.txt hits on
    abc123456.txt
    abc1234561.txt
    abc12345611.txt
    abc123456111.txt

    dir /b /a-d abc12????.txt hits on
    abc123456.txt
    abc1234561.txt
    abc12345611.txt
    abc123456111.txt

    dir /b /a-d abc1?????.txt hits on
    abc123456.txt
    abc1234561.txt
    abc12345611.txt
    abc123456111.txt

    dir /b /a-d abc??????.txt hits on
    abc123456.txt
    abc1234561.txt
    abc12345611.txt
    abc123456111.txt
    abc1234561111.txt
    abc12345611111.txt

    I have no idea why 3+ question marks at the end of the filename yield such wild results. Anyone else?

Leave a Reply