3

I have a directory containing a single .exe that I need to find using DIR. However, I also have files in the same directory that end in .vshost.exe. I always end up with both files matched to my *.exe pattern.

i.e the directory contains test.exe and test.vshost.exe (both files have the same name minus the extension.)

How can I match just the .exe, and not .vshost.exe? I feel like this should be relatively easy using * and ? but I can't seem to find much about excluding a file like this. Thanks.

3

This is unfortunately not possible with only the DIR command, however it can be combined with the FINDSTR command.

I'm focusing on the more general question, rather than the specific question regarding .exe files, but you can easily modify this to narrow it down.

The FINDSTR command supports regular expression searches on the output which allows us to filter out files with more than one period in the filename.

DIR /B | FINDSTR /V /R "[^\.]*\.[^\.]*\.[^\.]*$"

I would suggest wrapping into a FOR loop as follows to do something with the returned file list:

FOR /F "tokens=*" %%a IN ('DIR /B ^| FINDSTR /V /R "[^\.]*\.[^\.]*\.[^\.]*$"') DO ECHO %%a

Breakdown

In this explanation, <...> is a placeholder for things that will be explained later. It's only there to simplify.

  • FOR /F "tokens=*" %%a IN ('<...>') DO ECHO %%a
    Using "tokens=*" or "delims=" in your FOR loop allows processing filenames with spaces. Replace ECHO %%a with whatever command(s) you want to run.
  • DIR /B
    Using the /B switch on the DIR command uses bare format, including only the filenames. This is required for the FINDSTR command to function as we want.
  • ^|
    It is important to escape the | character when used inside the command portion of a FOR loop. Otherwise you'll get a syntax error because it thinks you're trying to pipe the incomplete FOR loop into something else.
  • FINDSTR /V /R "<...>"
    The /V switch tells FINDSTR to remove matches from the list and the /R switch turns on Regular Expression mode.
  • [^\.]*\.[^\.]*\.[^\.]*$
    • [^\.]* will match any string of characters that do not include the . character.
    • \. will match the . character.
    • $ is the "end of line" character, meaning that this regular expression must be at the end of the filename. This allows us to match files with any number of periods in the filename such as test.vhost.exe.bak.

Further Reading

0

this should work:

dir *.exe /b | findstr /i ".*[^\.]*.*\.exe$"

in words: find a string in .exe files that does not contain a dot other than the one in .exe

2
  • 2
    Consider adding a note explaining why this might work if you want to make it even more helpful. – Pillsbury IT Doughboy Mar 5 '19 at 17:15
  • 3
    The two .* in the pattern will allow any number of literal dots, and the class [^*\.] without a quantifier is pretty useless. – LotPings Mar 5 '19 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.