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
i
is not getting incremented each time I do it. - Concatenation on
strc
doesn'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 brackets
(
and)
).Delayed variables are referenced with
!var!
instead of%var%
.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:
Note: A line is also treated as a block:
With delayed expansion:
Delayed expansion is per default turned off at the command prompt. If you really need it, you can do:
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):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:
without delayed expansion:
Note:
setlocal
has no effect outside of batchfiles, sodelayedexpansion
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)