在 FOR /R LOOP 批处理命令期间重新创建子文件夹?

Posted

技术标签:

【中文标题】在 FOR /R LOOP 批处理命令期间重新创建子文件夹?【英文标题】:Recreate subfolders during a FOR /R LOOP batch command? 【发布时间】:2016-05-07 18:46:06 【问题描述】:

所以我正在编写一个脚本来扫描 mkv 文件并将任何 1080p 文件下转换为 720p。我目前正在使用“for /r”循环遍历每个文件以包含子文件夹。有没有办法可以将子文件夹重新创建到输出目的地?

这是我目前所拥有的(附:这是我的第一个脚本):

@echo off
set mediainfo="%~dp0MediaInfo.exe"
set result="%~dp0width.txt"
set handbrake="%~dp0HandBrakeCLI.exe"

SETLOCAL ENABLEDELAYEDEXPANSION
Set /P source=Enter source path:
Set /P output=Enter destination for converted files:
if %output:~-1%==\ set output=%output:~0,-1%
if not exist %output% mkdir %output% 
for /R %source% %%j in (*.mkv) do (
    Echo Filepath is: %%j
    %mediainfo% --Inform=Video;%%Width%% "%%j" > %result%
    set /P width=<%result%
    del %result%
    echo Width is: !width!
    if !width! == 1920 (%handbrake% -i "%%j" -o "%output%\%%~xnj" -f mkv -e x264 -q 20 --vfr -a 1,1 -E av_aac,ac3 -B 192 -w 1280 --keep-display-aspect -x level=4.1:vbv-bufsize=78125:vbv-maxrate=62500) else (echo No need to transcode.)
) 

现在,如果我有这样的结构:

 TV Show\Season 1
        \Season 2
        \Season 3

我希望源目录为“电视节目”,输出目录为将文件保留在相同的文件夹结构中。这可行吗?

编辑:我稍微更新了代码,添加了一个 if 语句来比较 %%~nxq(第 X 季)减去最后 2 个字符与“季节”一词,以确定工作文件夹是否在季节子文件夹中。唯一的问题是如果它是“第 10 季”,那么 if 比较将显示为“季”。尚未对其进行测试,我不确定是否有办法在 if 语句中使用通配符。这是更新的代码:

@echo off
set mediainfo="%~dp0MediaInfo.exe"
set result="%~dp0width.txt"
set handbrake="%~dp0HandBrakeCLI.exe"
SETLOCAL ENABLEDELAYEDEXPANSION
Set /P source=Enter source path:
echo Source path is: %source%
Set /P a=Enter destination for converted files:
set output=%a:"=%
if not %output:~-1%==\ (set output="%output%\") else (set output="%output%")
echo Destinition path is: %output%
if not exist %output% mkdir %output%
set dest=%output%
for /R %source% %%j in (*.mkv) do (
    Echo Filepath is: %%j
    for %%q in ("%%~dpj.") do (
        set sea=%%~nxq
        if "!sea:~0,-2!"=="Season" (
        set dest="%output:"=%%%~nxq\%%~xnj"
        set seafold="%output:"=%%%~nxq"
        if not exist !seafold! mkdir !seafold!
        ) else (
        set dest="%output:"=%%%~xnj"
        )
        echo Output Path is: !dest!
    )
    %mediainfo% --Inform=Video;%%Width%% "%%j" > %result%
    set /P width=<%result%
    del %result%
    echo Width is: !width!
    if !width! == 1920 (%handbrake% -i "%%j" -o !dest! -f mkv -e x264 -q 20 --vfr -a 1,1 -E av_aac,ac3 -B 192 -w 1280 --keep-display-aspect -x level=4.1:vbv-bufsize=78125:vbv-maxrate=62500) else (echo No need to transcode.)
) 

【问题讨论】:

您在哪个版本的 Windows 上运行?你考虑过 PowerShell 吗?它是一种更现代的脚本语言。你问的是可行的,在调用 handbreak 之前需要几行来解析来自 %j 的相对路径,然后 -o 参数更改为“%output%\%relpath%\%%~xnj”。解析相对路径会很痛苦,也许使用 SUBST 将驱动器号分配给您的源和输出路径,然后 %%~pj 给出没有驱动器号的相对路径。祝你好运。 脚本将在 Windows 7 机器上运行。我一开始考虑使用powershell,不记得为什么我没有使用它。我并不热衷于重写我刚刚开始工作的脚本,但如果一切都失败了,我会调查它。谢谢。 无法在if 中使用通配符(而且您不能在像%%q 这样的元变量上使用子字符串) - 为什么不使用if "!sea:~0,7!"=="Season " (...?你还有这个问题吗?如果是这样 - 更新的代码有什么问题?? 我不完全确定语法,但使用 "!sea:~0,6!" “季节”现在似乎起作用了。感谢您的帮助。 【参考方案1】:

当然。

for %%q in ("%%~dpj.") do echo %%~nxq

应该为您提供线索,因为到目前为止您已经完成了第一批...

~dpj 为您提供%%j 的驱动器/路径;然后使用怪癖来提取目录名称的最后一个元素的名称和扩展名)

【讨论】:

我会试试看的。我正在考虑尝试将 %%~pj 与 %source% 进行比较,并尝试删除公共路径。或者类似 set season=%%~pj:!source!=%% 但我无法让它工作......

以上是关于在 FOR /R LOOP 批处理命令期间重新创建子文件夹?的主要内容,如果未能解决你的问题,请参考以下文章

.less 批处理中的编译 for-loop 过早地结束批处理脚本

保持`for / f`重定向输出/在命令期间发生`do()`

r change_colname_for_loop.R

For loop in MATLAB,R,C programming language.

For loop in MATLAB,R,C programming language.

oracle For loop,隐式游标