变量未按预期运行
Variables are not behaving as expected
我一直在努力使这个批处理文件的语法正确,但我无法弄清楚为什么有些东西不起作用。
- 变量
i
每次我都没有递增。
strc
上的串联似乎没有串联。
这是我的代码:
set i=0
set "strc=concat:"
for %%f in (*.mp4) do (
set /a i+=1
set "str=intermediate%i%.ts"
set strc="%strc% %str%|"
ffmpeg -i "%%f" -c copy -bsf:v h264_mp4toannexb -f mpegts "%str%"
)
set strc="%strc:-1%"
ffmpeg -i "%strc%" -c copy -bsf:a aac_adtstoasc Output.mp4
你不是第一个落入著名的“延迟扩张陷阱”的人(你也不会是最后一个)。
如果你想使用一个你在同一个块中更改的变量,你需要延迟扩展(一个块是括号 (
和 )
中的一系列命令)。
延迟变量用!var!
而不是%var%
引用。
原因是方法,cmd
解析代码。一次完整的行或块被解析,在解析时用它们的值替换普通变量。延迟变量在运行时计算。
两个简单的批处理文件来演示:
setlocal EnableDelayedExpansion
set "var=hello"
if 1==1 (
set "var=world"
echo %var% !var!
)
setlocal EnableDelayedExpansion
for /L %%i in (1,1,5) do (
echo %random% !random!
)
注意:一行也被当做一个块:
set "var=old"
set "var=new" & echo %var%
延迟扩展:
setlocal EnableDelayedExpansion
set "var=old"
set "var=new" & echo !var!
延迟扩展在命令提示符下默认关闭。如果你真的需要它,你可以这样做:
cmd /V:ON /C "set "var=hello" & echo !var!"
还有一种方法可以在不延迟扩展的情况下执行相同的操作(但是 call
需要一些时间,所以速度较慢,但如果由于某种原因你不能/不想使用延迟扩展, 这是一个替代方案):
setlocal DISabledelayedexpansion
for /L %%i in (1 1 5) do (
call echo %random% %%random%%
)
这两种方式也可以用来显示array-like variables:
(这经常被问到“包含另一个变量的变量”或“嵌套变量”)
这是在不同情况下使用此类数组变量的集合:
延迟扩展:
setlocal ENableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
echo plain delayed: !var[%num%]!
for /L %%i in (4 1 4) do (
echo for delayed: !var[%%i]!
set a=%%i
call echo for delayed with variable: %%var[!a!]%%
)
没有延迟扩展:
setlocal DISableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
call echo plain called: %%var[%num%]%%
for /L %%i in (4 1 4) do (
call echo FOR called: %%var[%%i]%%
set a=%%i
call echo FOR called with variable: %%var[%a%]%%
)
注意:setlocal
在批处理文件之外没有效果,因此 delayedexpansion
仅有效:
- 在批处理文件中
- 当 cmd 启动时启用延迟扩展 (
cmd /V:ON
)(默认情况下,cmd 运行时延迟扩展 disabled)
(如果您对 technical background or even the advanced technical stuff 感兴趣,请点击链接)
我一直在努力使这个批处理文件的语法正确,但我无法弄清楚为什么有些东西不起作用。
- 变量
i
每次我都没有递增。 strc
上的串联似乎没有串联。
这是我的代码:
set i=0
set "strc=concat:"
for %%f in (*.mp4) do (
set /a i+=1
set "str=intermediate%i%.ts"
set strc="%strc% %str%|"
ffmpeg -i "%%f" -c copy -bsf:v h264_mp4toannexb -f mpegts "%str%"
)
set strc="%strc:-1%"
ffmpeg -i "%strc%" -c copy -bsf:a aac_adtstoasc Output.mp4
你不是第一个落入著名的“延迟扩张陷阱”的人(你也不会是最后一个)。
如果你想使用一个你在同一个块中更改的变量,你需要延迟扩展(一个块是括号 (
和 )
中的一系列命令)。
延迟变量用!var!
而不是%var%
引用。
原因是方法,cmd
解析代码。一次完整的行或块被解析,在解析时用它们的值替换普通变量。延迟变量在运行时计算。
两个简单的批处理文件来演示:
setlocal EnableDelayedExpansion
set "var=hello"
if 1==1 (
set "var=world"
echo %var% !var!
)
setlocal EnableDelayedExpansion
for /L %%i in (1,1,5) do (
echo %random% !random!
)
注意:一行也被当做一个块:
set "var=old"
set "var=new" & echo %var%
延迟扩展:
setlocal EnableDelayedExpansion
set "var=old"
set "var=new" & echo !var!
延迟扩展在命令提示符下默认关闭。如果你真的需要它,你可以这样做:
cmd /V:ON /C "set "var=hello" & echo !var!"
还有一种方法可以在不延迟扩展的情况下执行相同的操作(但是 call
需要一些时间,所以速度较慢,但如果由于某种原因你不能/不想使用延迟扩展, 这是一个替代方案):
setlocal DISabledelayedexpansion
for /L %%i in (1 1 5) do (
call echo %random% %%random%%
)
这两种方式也可以用来显示array-like variables:
(这经常被问到“包含另一个变量的变量”或“嵌套变量”)
这是在不同情况下使用此类数组变量的集合:
延迟扩展:
setlocal ENableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
echo plain delayed: !var[%num%]!
for /L %%i in (4 1 4) do (
echo for delayed: !var[%%i]!
set a=%%i
call echo for delayed with variable: %%var[!a!]%%
)
没有延迟扩展:
setlocal DISableDelayedExpansion
set "num=4"
set "var[%num%]=HELLO"
call echo plain called: %%var[%num%]%%
for /L %%i in (4 1 4) do (
call echo FOR called: %%var[%%i]%%
set a=%%i
call echo FOR called with variable: %%var[%a%]%%
)
注意:setlocal
在批处理文件之外没有效果,因此 delayedexpansion
仅有效:
- 在批处理文件中
- 当 cmd 启动时启用延迟扩展 (
cmd /V:ON
)(默认情况下,cmd 运行时延迟扩展 disabled)
(如果您对 technical background or even the advanced technical stuff 感兴趣,请点击链接)