6

I am trying to get a file with a specific extension from a directory. To do that I am using the following batch file code:

for %%f in (.\*.ext) do (
     echo %%f
)

This works fine, unless I have a file with .extsomething extension.
I tried adding the $ wildcard to get only the exact matching, but it doesn't show any results with it.

for %%f in (.\*.ext$) do (
     echo %%f
)

Since the * wildcard is accepted, why the $ is not considered?
How can I get only the files with the exact extension?

Garry White
  • 179
  • 1
  • 1
  • 8
  • 1
    The $ is more of a regular expression option. You would need to pipe the output of the DIR command to FINDSTR to have some limited regular expression capability. – Squashman Jan 21 '19 at 06:46
  • The short filename of the file matches your pattern. It will only use the first three letters of an extension in a short name. Filename.ext incl wildcards are matched against the short and long versions. – catcat Jan 21 '19 at 06:54
  • @catcat It is hard for me to follow what you are trying to tell me – Garry White Jan 21 '19 at 07:07
  • 1
    @GarryWhite I turned it into a longer answer. This was your actual question *Since the * wildcard is accepted, why the $ is not considered?*. The answer is to that - `$` is not a wildcard. – catcat Jan 21 '19 at 07:59
  • @catcat You are right, thanks for the explanation, I also updated my question to my real request. – Garry White Jan 21 '19 at 09:00

4 Answers4

9

Just add an if statement:

@echo off
for %%f in (*.ext) do (
    if "%%~xf"==".ext" echo %%f
)
Gerhard
  • 22,678
  • 7
  • 27
  • 43
  • It doesn't return any results :/ – Garry White Jan 21 '19 at 07:09
  • @GarryWhite do you have files with `.ext` in the dir? – Gerhard Jan 21 '19 at 07:11
  • My bad, I forgot to replace the `ext` with the actual extension :) I'll accept this answer since it is the closest to my initial code style – Garry White Jan 21 '19 at 07:13
  • For the first approach: use `if /I "%%~xf"==".ext"` to make it case-insensitive. For the second approach: `findstr /v ".ext?"` should actually read `findstr /v "\.ext$"` (`\.` to match a literal `.`, `$` to anchor the match to the end of the string)... – aschipfl Jan 21 '19 at 14:37
  • @aschipfl actually, that would get rid of the .ext part and keep .extens, but anyway, that part of the answer is now no longer relevant so removed it, seeing as OP focused on the 1st portion of the answer. – Gerhard Jan 21 '19 at 18:45
1

Use the Where command:

@For /F "Delims=" %%A In ('Where .:*.ext 2^>Nul') Do @Echo %%A
Compo
  • 36,585
  • 5
  • 27
  • 39
  • You'd need to (temporarily) delete variable `PATHEXT` in order not to get files like `*.ext.exe`, `*.ext.com`, etc.... – aschipfl Jan 21 '19 at 14:35
  • @aschipfl, I'll take your word for it, because I don't have a PC to check it against at this time, I would never touch that variable, _even temporarily_, and only a fool would create files named with `.???` as part of its name! – Compo Jan 21 '19 at 15:42
1

Firstly there is no $ wildcard. So it means a literal $.

Wildcards are matched against both names of a file. The file with the extension .txttttt has a short name extension of .txt. Because the first file in the dir didn't conflict with another file, and good to be represented by its 8.3 long name, it doesn't have a shortname as it's longname is valid. (PS the second text.txt has leading spaces using \\?\C:\ test.txt).

C:\>dir /x t*.txt
 Volume in drive C is Windows
 Volume Serial Number is 9EE7-AAA5

 Directory of C:\

17/01/2019  11:23 AM               250              test.txt
26/02/2018  07:30 PM           195,776 TEST~1.TXT     test.txt
21/01/2019  05:50 PM                 5 TEST~2.TXT   test.txtttt
               3 File(s)        196,031 bytes
               0 Dir(s)  752,444,428,288 bytes free

See Command to run a .bat file

catcat
  • 131
  • 5
0

The following works for me

Dir /b *.txt* > fileName.out