在cmd批处理脚本中递归for循环,获取相对于脚本文件的匹配文件路径

在cmd批处理脚本中递归for循环,获取相对于脚本文件的匹配文件路径

我试图通过从%~dp0中减去 来实现这一点%%~dpa,其中%%afor 循环变量是 。如果有人知道更好的方法,请提供建议。

我的代码如下:

@echo off
setlocal enabledelayedexpansion
for /r %%a in (*.mp4) do (
    set "file=%%~dpa"
    set "scriptpath=%~dp0"
    set "result=%!file!:!scriptpath!=%"
    echo !result!
    echo !scriptpath!
)

pause

其结果是:

D:\path\to script\file\=
D:\path\to script\file\

我已经玩了好几个小时了,但还是无法让它工作。感谢您的时间!

答案1

如何获取相对于脚本文件路径的路径匹配的文件?

您几乎已经到达...

使用以下批处理文件(我已注释掉脚本中位置错误或不正确的行):

@echo off
setlocal enabledelayedexpansion
set "scriptpath=%~dp0"
for /r %%a in (*.mp4) do (
    rem set "file=%%~dpa"
    set "file=%%a"
    rem set "scriptpath=%~dp0"
    rem set "result=%!file!:!scriptpath!=%"
    call set "result=%%file:%scriptpath%=%%"
    echo !result!
    echo !scriptpath!
)

请阅读CMD 变量编辑替换 - Windows CMD - SS64.com解释为什么call需要当有一个变量时价值您正在尝试替换。

例子:

F:\test>dir /b /s *.mp4
F:\test\3.mp4
F:\test\2.mp4
F:\test\1.mp4
F:\test\sub 2\1.mp4
F:\test\sub 2\2.mp4
F:\test\sub 2\3.mp4
F:\test\sub 1\1.mp4
F:\test\sub 1\2.mp4
F:\test\sub 1\3.mp4

F:\test>test
3.mp4
F:\test\
2.mp4
F:\test\
1.mp4
F:\test\
sub 2\1.mp4
F:\test\
sub 2\2.mp4
F:\test\
sub 2\3.mp4
F:\test\
sub 1\1.mp4
F:\test\
sub 1\2.mp4
F:\test\
sub 1\3.mp4
F:\test\

F:\test>

答案2


  • 文件夹树:
F:\2021-SU\Q1635032> tree /f /a|find/v "Q635032.cmd"

Folder PATH listing for volume 2nd
Volume serial number is FACF-B9ED
F:.
|   file 00.mp4
|
+---other sub dir
|   |   other file 00.mp4
|   |
|   \---sub dir 1
|           other file 01.mp4
|
\---some sub dir
    |   some file 00.mp4
    |
    \---sub dir 1
            some file 01.mp4

不带变量的选项,每个包含 .mp4 的文件夹仅运行一次

  • 仅列出文件夹名称:
@echo off

cd /d "%~dp0" && for /r /d %%i in (.
    )do dir/b/a "%%~i\*.mp4" >nul && echo=.\%%~nxi

1.转到你的 bat 文件夹:cd/d "%~dp0"

2.递归循环所有文件夹:for /r /d %%i in (.)do ...

3.在每个文件夹中,检查其中是否有 mp4:dir /b/a "%%~i\*.mp4"

4.如果其中没有 mp4,则省略错误:...dir ... >nul

5.如果dir .mp4 return 0,使用运算符执行echo\ Folder_Name&& echo=.\%%~nxi

  • 观察:1当文件夹包含多个 mp4 文件时,这些选项不会列出重复的文件夹名称

  • 结果/输出:
F:\2021-SU\Q1635032> Q635032.cmd
.\Q1635032
.\other sub dir
.\sub dir 1
.\some sub dir
.\sub dir 1

  • 列出文件夹的相对路径:
@echo off && cd/d "%~dp0"
 
subst .: "%~dp0" && .: && for /r /d %%i in (.)do (
     dir /b/a "%%~i\*.mp4" >nul && echo=.%%~pnxi )

cd /d "%~dp0" & subst /d .:

1.转到你的 bat 文件夹:cd/d "%~dp0"

2.为您的文件夹分配一个虚拟驱动器:subst .: "%~dp0"

3.进入创建的虚拟驱动器:.. && .:

4.递归循环所有文件夹:for /r /d %%i in (.)do ...

5.在每个文件夹中,检查其中是否有 mp4:dir/b/a "%%~i\*.mp4"

6.如果其中没有 mp4,则省略错误:...dir ... >nul

7.如果dir .mp4 return 0,使用运算符执行echo..&& echo=.%%~pnxi

8.返回原始目录/文件夹,退出虚拟驱动器:cd /d "%~dp0"

9.运行时创建的虚拟驱动器不再需要,请将其删除:subst /d .:

  • 观察:2虚拟单元.:,将无法在图形用户界面中提供交互能力,从而避免脚本运行时受到用户的干扰:

  • 结果/输出:
F:\2021-SU\Q1635032> Q635032.cmd
.\
.\other sub dir
.\other sub dir\sub dir 1
.\some sub dir
.\some sub dir\sub dir 1

观察:3 有关For /R /D循环命令:


要隐藏根文件夹/工作目录,仅列出文件夹名称,例如:

F:\2021-SU\Q1635032> Q635032.cmd
.\Q1635032
.\other sub dir
.\sub dir 1
.\some sub dir
.\sub dir 1

您可以使用前两个选项的混合选项:

@echo off && cd/d "%~dp0" 

subst .: "%~dp0" && .: && for /r /d %%i in (.)do ( 
     dir /b /a "%%~i\*.mp4">nul && echo=.\%%~nxi )
    
cd/d "%~dp0" && subst /d .:

观察:4- 使用For循环可以扩展变量:

    %~i   - expands %i removing any surrounding quotes (")
    %~fi  - expands %i to a fully qualified path file/dir name only
    %~ni  - expands %i to a file/dir name only
    %~xi  - expands %i to a file/dir extension only
    
    %%~nxi => expands %%~i to a file/dir name and extension
  • Use the FOR variable syntax replacement:
        %~pI        - expands %I to a path only
        %~nI        - expands %I to a file name only
        %~xI        - expands %I to a file extension only
  • The modifiers can be combined to get compound results:
        %~pnI       - expands %I to a path and file name only
        %~pnxI      - expands %I to a path, file name and extension only

相关内容