【问题标题】:Find a FolderName\file.name combination(s) recursively in a batch file and return the full path(s)在批处理文件中递归查找 FolderName\file.name 组合并返回完整路径
【发布时间】:2022-01-26 10:10:00
【问题描述】:

我希望递归地在目录中的特定文件夹名称中查找特定文件名,如果存在匹配项或多个匹配项,则返回完整路径。我正在寻找一种模式搜索,它甚至可以使用 3 部分查找,即(folderA\folderB\file.name)。但是2现在就可以了。到目前为止,我的努力使我做到了这一点。但这非常慢。 16 多秒才能找到匹配项。

   ::recursively find foldername\file.name combination

   cd C:\searchFolder
   for /r %a in (FolderName) do @if exist "%~fa\file.name" echo %~fa

我只需要冒险大约 2 到 4 层深度并拉起第一个文件夹\file.ext 匹配项并获取完整路径。有没有更快的方法来做到这一点,也许是 dir 命令或排除列表,甚至是真正的 *folder\file 模式搜索。

【问题讨论】:

    标签: batch-file recursion search design-patterns directory


    【解决方案1】:

    让我们首先通过示例文件夹结构和C:\SearchFolder 的每个子文件夹中名称为file.name 的文件来阐明任务:

    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
    

    可以使用以下方法创建包含文件的文件夹结构:

    @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
    

    示例结构是在 Windows 命令提示符窗口中运行 tree /F C:\SearchFolder 时输出的。

    应该只在C:\SearchFolder 的前三个子文件夹级别中搜索名称为file.name 的文件,并且找到的具有该名称的文件的路径必须以FolderA\FolderB\ 结尾。

    这可以使用以下批处理文件来完成:

    @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
    

    输出是:

    "C:\SearchFolder\FolderA\FolderA\FolderB\file.name"
    "C:\SearchFolder\FolderB\FolderA\FolderB\file.name"
    "C:\SearchFolder\FolderA\FolderB\file.name"
    

    因此,只需三个 FOR 命令即可在 C:\SearchFolder 的三个子文件夹中搜索文件 file.name,这些子文件夹存储在名称为 FolderB 的文件夹中姓名FolderA

    要了解所使用的命令及其工作原理,请打开command prompt 窗口,在那里执行以下命令,并仔细阅读每个命令显示的所有帮助页面。

    • dir /?
    • echo /?
    • endlocal /?
    • for /?
    • md /?
    • set /?
    • setlocal /?
    • tree /?

    阅读有关Using command redirection operators 的Microsoft 文档,了解>2>nul。重定向运算符 > 必须在 FOR 命令行上使用插入字符 ^ 转义,以便在 Windows 命令解释器在执行命令 FOR 之前处理此命令行时被解释为文字字符> 在后台启动的单独命令进程中执行嵌入的dir 命令行,%ComSpec% /c' 中的命令行作为附加参数附加。

    PS:rd /Q /S C:\SearchFolder 删除整个示例文件夹结构。

    【讨论】:

    • 这正是我想要的。这很有效,我现在对“for”循环参数有了更好的理解。谢谢。
    【解决方案2】:

    如果您想限制级别,如您的问题中所述,(但未澄清),也许使用 Robocopy.exe 也可以让您仅深入了解所需的级别数.

    作为一个简单的示例,使用下面的第一个脚本来创建您的测试目录结构:

    @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"
    )
    

    然后使用以下脚本列出您找到的路径:

    @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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-27
      • 2020-04-27
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      相关资源
      最近更新 更多