I'm looking to find a specific file name within a specific folder name in a directory recursively and return the full path if there is a match or multiple matches. I'm looking for a pattern search that can possibly even use a 3 part lookup i.e (folderA\folderB\file.name). But 2 will do for now. So far my efforts have brought me to this. But it is terribly slow. 16+ seconds to find the match.
::recursively find foldername\file.name combination
cd C:\searchFolder
for /r %a in (FolderName) do @if exist "%~fa\file.name" echo %~fa
I only need to venture about 2 to 4 levels deep and pull up the first folder\file.ext match and grab the full path. Is there a faster way to do this, with maybe the dir command or an exclusion list or even a true *folder\file pattern search.
Let us first clarify the task with an example folder structure and a file with name file.name
in each subfolder of C:\SearchFolder
:
C:\SearchFolder
├───FolderA
│ │ file.name
│ │
│ ├───FolderA
│ │ │ file.name
│ │ │
│ │ ├───FolderA
│ │ │ │ file.name
│ │ │ │
│ │ │ ├───FolderA
│ │ │ │ file.name
│ │ │ │
│ │ │ └───FolderB
│ │ │ file.name
│ │ │
│ │ └───FolderB
│ │ │ file.name
│ │ │
│ │ ├───FolderA
│ │ │ file.name
│ │ │
│ │ └───FolderB
│ │ file.name
│ │
│ └───FolderB
│ │ file.name
│ │
│ ├───FolderA
│ │ │ file.name
│ │ │
│ │ ├───FolderA
│ │ │ file.name
│ │ │
│ │ └───FolderB
│ │ file.name
│ │
│ └───FolderB
│ │ file.name
│ │
│ ├───FolderA
│ │ file.name
│ │
│ └───FolderB
│ file.name
│
└───FolderB
│ file.name
│
├───FolderA
│ │ file.name
│ │
│ ├───FolderA
│ │ │ file.name
│ │ │
│ │ ├───FolderA
│ │ │ file.name
│ │ │
│ │ └───FolderB
│ │ file.name
│ │
│ └───FolderB
│ │ file.name
│ │
│ ├───FolderA
│ │ file.name
│ │
│ └───FolderB
│ file.name
│
└───FolderB
│ file.name
│
├───FolderA
│ │ file.name
│ │
│ ├───FolderA
│ │ file.name
│ │
│ └───FolderB
│ file.name
│
└───FolderB
│ file.name
│
├───FolderA
│ file.name
│
└───FolderB
file.name
That folder structure with the files can be created using:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BaseFolder=C:\SearchFolder"
for %%G in (A B) do (
for %%H in (A B) do (
for %%I in (A B) do (
for %%J in (A B) do (
md "%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\Folder%%J"
echo "%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\Folder%%J">"%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\Folder%%J\file.name"
)
echo "%BaseFolder%\Folder%%G\Folder%%H\Folder%%I">"%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\file.name"
)
echo "%BaseFolder%\Folder%%G\Folder%%H">"%BaseFolder%\Folder%%G\Folder%%H\file.name"
)
echo "%BaseFolder%\Folder%%G">"%BaseFolder%\Folder%%G\file.name"
)
endlocal
The example structure is output on running tree /F C:\SearchFolder
in a Windows command prompt window.
There should be searched for files with name file.name
in just the first three subfolder levels of C:\SearchFolder
and the found files with that name must have a path ending with FolderA\FolderB\
.
That can be done using the following batch file:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BaseFolder=C:\SearchFolder"
set "FolderName1=FolderA"
set "FolderName2=FolderB"
set "FileName=file.name"
for /F "delims=" %%I in ('dir "%BaseFolder%" /AD /B 2^>nul') do (
for /F "delims=" %%J in ('dir "%BaseFolder%\%%I\%FolderName1%\%FolderName2%\%FileName%" /A-D /B 2^>nul') do echo "%BaseFolder%\%%G\%FolderName1%\%FolderName2%\%FileName%"
)
for /F "delims=" %%J in ('dir "%BaseFolder%\%FolderName1%\%FolderName2%\%FileName%" /A-D /B 2^>nul') do echo "%BaseFolder%\%FolderName1%\%FolderName2%\%FileName%"
endlocal
The output is:
"C:\SearchFolder\FolderA\FolderA\FolderB\file.name"
"C:\SearchFolder\FolderB\FolderA\FolderB\file.name"
"C:\SearchFolder\FolderA\FolderB\file.name"
So there are just three FOR commands necessary to search for file file.name
in the thirst three subfolders of C:\SearchFolder
being stored in a folder with name FolderB
with is inside a folder with name FolderA
.
To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.
dir /?
echo /?
endlocal /?
for /?
md /?
set /?
setlocal /?
tree /?
Read the Microsoft documentation about Using command redirection operators for an explanation of >
and 2>nul
. The redirection operator >
must be escaped with caret character ^
on FOR command lines to be interpreted as literal character when Windows command interpreter processes this command lines before executing command FOR which executes the embedded dir
command line with using a separate command process started in background with %ComSpec% /c
and the command line within '
appended as additional arguments.
PS: rd /Q /S C:\SearchFolder
deletes the entire example folder structure.