I'm currently trying to do some batch merging and renaming and am facing the following problem (this is not the actual code, but rather a MWE demonstrating the problem):
@echo off
set /p "arg=Input the path to target directory (defaults to current directory if left empty): "
for %%f in ("%arg%\*.mkv") do (
echo %%~nf
set "out=%%~nf"
echo %out%
)
pause
My problem is that these two echoes do not print the same values. The first one prints the correct thing (file name), the second one prints something random like Echo is OFF or the last file name of the directory.
After a bit of searching I found a mention of using delayed expansion of variables (setlocal EnableDelayedExpansion), but that causes a problem, because the directory path the user inputs may contain exclamation marks, which get removed if I do that (and so the for loop is not executed at all).
How do I properly go about setting variables in a for loop?
UPDATE
With the help of Dennis's solution and some additional trial and error, I was finally able to fix the original code and it now works. For anyone interested, this is what I was attempting to do:
for %%f in ("%arg%\*.mkv") do (
set "n=%%~nf"
setlocal EnableDelayedExpansion
mkvmerge -o "!n:~15,10! !n:~25!" "!n!_Track00.h264" ...
endlocal
)
The actual command is in fact much longer so I'm not pasting it in its entirety, just pasting enough to demonstrate what is required in it as arguments. I used the variable n because %%~nf does not function well inside the delayed expansion environment (i.e. the !s get removed), and I don't know how to dereference double-percented variables (parameters?) with delayed expansion.
Additionally, attempting to
set "out=%n:~15,10% %n:~25%"
before setting delayed expansion and then running
mkvmerge -o "!out!" ...
did not delay expansion properly so the above code was what I ended up with.