I think the only safe way is to establish loops for all the parts: the drive letter, the folder B
(anything, *
) and the folder C
(85*
). The inner-most loop in the following code example iterates once only and returns the file without accessing the file system as there is no wildcard *
or ?
(that is the nature of for
); that is why if exist
is used -- twice in order to match files only but not directories (note the trailing \
for the second one, not
to be not fulfilled for folders):
for %%A in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
for /D %%B in ("%%A:\Org\App\*") do (
for /D %%C in ("%%~B\85*") do (
for %%D in ("%%~C\SQL Scripts\Miscellaneous\CRErrorFinder.exe") do (
if exist "%%~D" if not exist "%%~D\" (
echo(%%~D
)
)
)
)
)
The found path(s) is/are simply echoed.
There might be another way using dir /S
and findstr
, but you still have to loop through the drive letters:
for %%A in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
dir /B /S /A:-D "%%A:\CRErrorFinder.exe" | findstr /R /I /X /C:".:\\Org\\App\\[^\\][^\\]*\\85[^\\]*\\SQL Scripts\\Miscellaneous\\CRErrorFinder\.exe"
)
Note that .
means any character, \\
is a literal \
, [^\\]
is a character except \
, *
means the previous expression zero or more times and \.
is a literal .
.
Instead of looping through the alphabet you could gather the actually available drives on your system by wmic
and capture them by for /F
like this:
All drives including network drives and such established by subst
:
for /F "skip=1" %%A in ('wmic LogicalDisk get DeviceID') do for /F "delims=:" %%A in ("%%A") do (
rem %%A holds the pure drive letter.
)
Local drives only:
for /F "skip=1" %%A in ('wmic Volume where "DriveLetter is not Null" get DriveLetter') do for /F "delims=:" %%A in ("%%A") do (
rem %%A holds the pure drive letter.
)
Or (a bit faster):
for /F "delims=:\ " %%A in ('mountvol ^| find ":\"') do (
rem %%A holds the pure drive letter.
)
These methods can be used for both of the aforementioned approaches instead of the for %%A
loop.