在批处理文件中递归查找 FolderName\file.name 组合和 return 完整路径
Find a FolderName\file.name combination(s) recursively in a batch file and return the full path(s)
我希望以递归方式在目录中的特定文件夹名称中查找特定文件名,如果存在一个或多个匹配项,则 return 查找完整路径。我正在寻找一种模式搜索,它甚至可以使用 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 个级别并拉起第一个 folder\file.ext 匹配并获取完整路径。有没有更快的方法可以使用 dir 命令或排除列表,甚至是真正的 *folder\file 模式搜索。
让我们首先通过示例文件夹结构和 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
示例结构在 运行 tree /F C:\SearchFolder
的 Windows 命令提示符 window 中输出 window。
应该在 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
的 thirst 三个子文件夹中搜索文件 file.name
并存储在一个名为FolderB
位于名称为 FolderA
.
的文件夹中
要了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
dir /?
echo /?
endlocal /?
for /?
md /?
set /?
setlocal /?
tree /?
阅读有关 Using command redirection operators 的 Microsoft 文档,了解 >
和 2>nul
的解释。重定向运算符 >
必须在 上使用脱字符 ^
进行转义,以便 命令行在 Windows 命令解释器处理此命令时被解释为文字字符执行命令 FOR 之前的行,它在一个单独的命令进程中执行嵌入的 dir
命令行,在后台启动 %ComSpec% /c
和 '
中的命令行作为附加参数附加。
PS: rd /Q /S C:\SearchFolder
删除整个示例文件夹结构。
如果您想要限制级别,如您的问题中所述,(但未阐明),也许使用 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
我希望以递归方式在目录中的特定文件夹名称中查找特定文件名,如果存在一个或多个匹配项,则 return 查找完整路径。我正在寻找一种模式搜索,它甚至可以使用 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 个级别并拉起第一个 folder\file.ext 匹配并获取完整路径。有没有更快的方法可以使用 dir 命令或排除列表,甚至是真正的 *folder\file 模式搜索。
让我们首先通过示例文件夹结构和 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
示例结构在 运行 tree /F C:\SearchFolder
的 Windows 命令提示符 window 中输出 window。
应该在 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
的 thirst 三个子文件夹中搜索文件 file.name
并存储在一个名为FolderB
位于名称为 FolderA
.
要了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
dir /?
echo /?
endlocal /?
for /?
md /?
set /?
setlocal /?
tree /?
阅读有关 Using command redirection operators 的 Microsoft 文档,了解 >
和 2>nul
的解释。重定向运算符 >
必须在 上使用脱字符 ^
进行转义,以便 命令行在 Windows 命令解释器处理此命令时被解释为文字字符执行命令 FOR 之前的行,它在一个单独的命令进程中执行嵌入的 dir
命令行,在后台启动 %ComSpec% /c
和 '
中的命令行作为附加参数附加。
PS: rd /Q /S C:\SearchFolder
删除整个示例文件夹结构。
如果您想要限制级别,如您的问题中所述,(但未阐明),也许使用 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