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 ie (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
.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very 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.
If you're wanting to limit the levels, as mentioned in your question, (but not clarified) , perhaps using Robocopy.exe
will allow you to drill down only the required number of levels too.
As a quick example, use the first script below to create your test directory structure:
@Echo Off
SetLocal EnableExtensions
Set "BaseFolder=%UserProfile%\Desktop\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 (
For %%K In (A B) Do (
For %%L In (A B) Do (
MD "%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\Folder%%J\Folder%%K\Folder%%L"
CD.>"%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\Folder%%J\Folder%%K\Folder%%L\file.name"
)
CD.>"%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\Folder%%J\Folder%%K\file.name"
)
CD.>"%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\Folder%%J\file.name"
)
CD.>"%BaseFolder%\Folder%%G\Folder%%H\Folder%%I\file.name"
)
CD.>"%BaseFolder%\Folder%%G\Folder%%H\file.name"
)
CD.>"%BaseFolder%\Folder%%G\file.name"
)
Then use the following script to list your found paths:
@Echo Off
SetLocal EnableExtensions
Set "BaseFolder=%UserProfile%\Desktop\SearchFolder"
Set "FolderName1=FolderA"
Set "FolderName2=FolderB"
Set "FileName=file.name"
For /F "Tokens=*" %%G In ('%SystemRoot%\System32\Robocopy.exe
"%BaseFolder%" "Null" "%FileName%" /FP /L /LEV:5 /NC /NDL /NJH /NJS /NS /S ^|
%SystemRoot%\System32\findstr.exe /RI "\\%FolderName1%\\%FolderName2%\\%FileName%$"
') Do Echo %%G
Pause
GoTo :EOF
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.