Windows 调用另一个批处理时的批处理、for 循环和文件属性
Windows Batch, for loop and file attributes while calling another batch
我最近开始将我所有的视频文件转换为 MP4 以用于流式传输,并且到目前为止使用批处理没有问题。
现在我有 6000 多个视频要转换,需要某种我可以操作的队列系统。
这是我当前的代码,用于将目录中的所有内容转换为单独文件夹中的命令。
@echo off
setlocal disabledelayedexpansion
set dirs=D:\ANIME E:\ANIME F:\ANIME
for %%a in (%dirs%) do (
echo %%a
pushd %%a
for /f "tokens=* delims= " %%f IN ('dir/b/s *.avi *.mkv *.m4v *.mpeg *.mpg') do (
echo D:\handbrake\HandBrakeCLI.exe -i "%%f" -e qsv_h264 -q 20 -E fdk_haac -B 196 -R Auto -D 0,0,0,0 --audio-copy-mask aac,ac3,dtshd,dts,mp3 --audio-fallback copy:* --subtitle=1 --subtitle-default --subtitle-forced --subtitle-burn -o "%%~dpf%%~nf.mp4" > "D:\batch\%%~nf.bat"
echo del /F "%%f" >> "D:\batch\%%~nf.bat"
)
)
这很好用,让我可以调用 1000 个 bat 文件,这就是问题所在。
许多文件都有特殊字符,如 !在他们的名字中弄乱了我用来循环这些的 for 循环。我在处理之前将文件设置为只读,所以我的其他批次不会尝试转换同一个文件(我 运行 一次转换 3 个)。
我找到了使用 ENABLEDELAYEXPANSION 的解决方法,但在几次循环后我会收到错误消息,说我超出了最大调用次数。
@echo off
setlocal enableextensions
echo Starting loop
goto loop
:loop
for %%f in (D:\batch\*.bat) do (
set ATTRIBS=%%~af
setlocal enabledelayedexpansion
set READ_ATTRIB=!ATTRIBS:~1,1!
if !READ_ATTRIB!==- (
setlocal disabledelayedexpansion
attrib +R "%%f"
call "%%f"
)
timeout /t 2 /nobreak
goto loop
)
endlocal
通常你会说只要改变!变量到 % 并删除 delayedexpansion,但这让我在获取文件属性时出错。
set READ_ATTRIB=%ATTRIBS:~1,1%
if %READ_ATTRIB%==- (
不会给我任何结果并且错误 ( 是意外的
如果我回显 READ_ATTRIB 结果总是 ~1,1 并且当回显其他人时我会得到 ECHO IS OFF.
有什么方法可以不使用 delayedexpansion 或者在几次循环后我不会出错?
32 is the deepest level of setlocal
when used in batch file。您需要使用 setlocal
- endlocal
对,类似于一对 (
左括号和 )
右括号。请参阅下面的大写 ENDLOCAL
。
@echo off
setlocal enableextensions
echo Starting loop
goto loop
:loop
for %%f in (D:\batch\*.bat) do (
set ATTRIBS=%%~af
setlocal enabledelayedexpansion
set READ_ATTRIB=!ATTRIBS:~1,1!
if !READ_ATTRIB!==- (
setlocal disabledelayedexpansion
attrib +R "%%f"
call "%%f"
ENDLOCAL
)
ENDLOCAL
timeout /t 2 /nobreak
REM this was totally mazy: goto loop
)
endlocal
此外,您原始代码中的后者 goto loop
导致 for %%f
循环针对同一数据集无限期地初始化,即循环体中的 %%f
指的是一直只归档。见大写 REM
.
我最近开始将我所有的视频文件转换为 MP4 以用于流式传输,并且到目前为止使用批处理没有问题。 现在我有 6000 多个视频要转换,需要某种我可以操作的队列系统。
这是我当前的代码,用于将目录中的所有内容转换为单独文件夹中的命令。
@echo off
setlocal disabledelayedexpansion
set dirs=D:\ANIME E:\ANIME F:\ANIME
for %%a in (%dirs%) do (
echo %%a
pushd %%a
for /f "tokens=* delims= " %%f IN ('dir/b/s *.avi *.mkv *.m4v *.mpeg *.mpg') do (
echo D:\handbrake\HandBrakeCLI.exe -i "%%f" -e qsv_h264 -q 20 -E fdk_haac -B 196 -R Auto -D 0,0,0,0 --audio-copy-mask aac,ac3,dtshd,dts,mp3 --audio-fallback copy:* --subtitle=1 --subtitle-default --subtitle-forced --subtitle-burn -o "%%~dpf%%~nf.mp4" > "D:\batch\%%~nf.bat"
echo del /F "%%f" >> "D:\batch\%%~nf.bat"
)
)
这很好用,让我可以调用 1000 个 bat 文件,这就是问题所在。 许多文件都有特殊字符,如 !在他们的名字中弄乱了我用来循环这些的 for 循环。我在处理之前将文件设置为只读,所以我的其他批次不会尝试转换同一个文件(我 运行 一次转换 3 个)。
我找到了使用 ENABLEDELAYEXPANSION 的解决方法,但在几次循环后我会收到错误消息,说我超出了最大调用次数。
@echo off
setlocal enableextensions
echo Starting loop
goto loop
:loop
for %%f in (D:\batch\*.bat) do (
set ATTRIBS=%%~af
setlocal enabledelayedexpansion
set READ_ATTRIB=!ATTRIBS:~1,1!
if !READ_ATTRIB!==- (
setlocal disabledelayedexpansion
attrib +R "%%f"
call "%%f"
)
timeout /t 2 /nobreak
goto loop
)
endlocal
通常你会说只要改变!变量到 % 并删除 delayedexpansion,但这让我在获取文件属性时出错。
set READ_ATTRIB=%ATTRIBS:~1,1%
if %READ_ATTRIB%==- (
不会给我任何结果并且错误 ( 是意外的 如果我回显 READ_ATTRIB 结果总是 ~1,1 并且当回显其他人时我会得到 ECHO IS OFF.
有什么方法可以不使用 delayedexpansion 或者在几次循环后我不会出错?
32 is the deepest level of setlocal
when used in batch file。您需要使用 setlocal
- endlocal
对,类似于一对 (
左括号和 )
右括号。请参阅下面的大写 ENDLOCAL
。
@echo off
setlocal enableextensions
echo Starting loop
goto loop
:loop
for %%f in (D:\batch\*.bat) do (
set ATTRIBS=%%~af
setlocal enabledelayedexpansion
set READ_ATTRIB=!ATTRIBS:~1,1!
if !READ_ATTRIB!==- (
setlocal disabledelayedexpansion
attrib +R "%%f"
call "%%f"
ENDLOCAL
)
ENDLOCAL
timeout /t 2 /nobreak
REM this was totally mazy: goto loop
)
endlocal
此外,您原始代码中的后者 goto loop
导致 for %%f
循环针对同一数据集无限期地初始化,即循环体中的 %%f
指的是一直只归档。见大写 REM
.