批处理 - 在 for 循环中设置变量

Batch - Set variables in for loop

我目前正在尝试进行一些批量合并和重命名,但遇到了以下问题(这不是实际代码,而是演示问题的 MWE):

@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

我的问题是这两个回显打印的值不同。第一个打印正确的东西(文件名),第二个打印一些随机的东西,比如 Echo is OFF 或目录的最后一个文件名。

经过一番搜索后,我发现有人提到使用变量的延迟扩展(setlocal EnableDelayedExpansion),但这会导致问题,因为用户输入的目录路径可能包含感叹号,如果我这样做,感叹号会被删除(因此根本不执行 for 循环)。

如何正确地在 for 循环中设置变量?

更新

在 Dennis 的解决方案和一些额外的试验和错误的帮助下,我终于能够修复原始代码并且它现在可以工作了。对于任何感兴趣的人,这就是我试图做的事情:

for %%f in ("%arg%\*.mkv") do (
  set "n=%%~nf"

  setlocal EnableDelayedExpansion
  mkvmerge -o "!n:~15,10! !n:~25!" "!n!_Track00.h264" ...
  endlocal
)

实际的命令实际上要长得多,所以我不会完整地粘贴它,只是粘贴足够多的内容来证明其中需要什么作为参数。我使用变量 n 是因为 %%~nf 在延迟扩展环境中不能很好地运行(即 !s 被删除),而且我不知道如何通过延迟扩展取消引用双百分比变量(参数?)。

另外,尝试

set "out=%n:~15,10% %n:~25%"

设置延迟展开前运行

mkvmerge -o "!out!" ...

没有正确延迟扩展,所以上面的代码就是我最终得到的。

你应该试试这个:

@echo off
set "arg=."
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"
  setlocal EnableDelayedExpansion
  echo !out!
  endlocal
)
pause