Search code examples
batch-filerecursionsearchdesign-patternsdirectory

Find a FolderName\file.name combination(s) recursively in a batch file and return the full path(s)


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.


Solution

  • 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.