I’ve been wrestling trying to get the syntax right on this batch file and I cannot figure out why some things aren’t working.
- The variable
iis not getting incremented each time I do it.
- Concatenation on
strcdoesn’t seem to concatenate.
Here is my code:
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
You are not the first, who fell into the famous “delayed expansion trap” (and you won’t be the last).
You need delayed expansion if you want to use a variable, that you changed in the same block (a block is a series of commands within parentheses
Delayed variables are referenced with
!var! instead of
Reason is the way,
cmd parses the code. A complete line or block is parsed at once, replacing normal variables with their value at parse time. Delayed variables are evaluated at runtime.
Two simple batch files to demonstrate:
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! )
Note: A line is also treated as a block:
set "var=old" set "var=new" & echo %var%
With delayed expansion:
setlocal EnableDelayedExpansion set "var=old" set "var=new" & echo !var!
Delayed expansion is per default turned off at the command prompt. If you really need it, you can do:
cmd /V:ON /C "set "var=hello" & echo !var!"
Also there is a way to do the same without delayed expansion (but
call costs some time, so it’s slower, but if for some reason you can’t / don’t want to use delayed expansion, it’s an alternative):
setlocal DISabledelayedexpansion for /L %%i in (1 1 5) do ( call echo %random% %%random%% )
Both methods can also be used to display array-like variables:
(This is often asked like “variable which contains another variable” or “nested variables”)
Here is a collection for using such array-like variables in different situations:
With delayed expansion:
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!]%% )
without delayed expansion:
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 has no effect outside of batchfiles, so
delayedexpansion works only:
- In batch files
- When the cmd was started with delayed expansion enabled (
cmd /V:ON) (by default, the cmd runs with delayed expansion disabled)