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

Posted

技术标签:

【中文标题】批处理 - 在 for 循环中设置变量【英文标题】:Batch - Set variables in for loop 【发布时间】:2016-04-14 20:36:41 【问题描述】:

我目前正在尝试进行一些批量合并和重命名,并面临以下问题(这不是实际代码,而是演示问题的 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!" ...

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

【问题讨论】:

你应该使用!而不是 % 在 for 循环中,所以 echo !out!。我建议看here 启用延迟扩展使用!在循环内。 Batch file variables initialized in a for loop的可能重复 【参考方案1】:

你应该试试这个:

@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

【讨论】:

我已经更新了问题。这给了我一个关于 setlocal 递归深度的错误。 已编辑,您需要 endlocal 而不是 setlocal disable 好的,这个效果更好,但仍然有问题,因为它仍然会删除文件名中的感叹号(它们也可以包含!s)。有没有办法避免名称中的问号被全部删除? 已编辑,这应该可以。我还修复了“如果没有输入”的情况。 我已经设法在我的代码中实现了这个解决方案。我已经更新了我的问题并接受了这个答案。感谢您的帮助。

以上是关于批处理 - 在 for 循环中设置变量的主要内容,如果未能解决你的问题,请参考以下文章

在 FOR 循环批处理语法中使用变量进行字符串替换

处理在多个 for 循环中声明的变量的最惯用方法是啥? [关闭]

我将如何隔离或仅将第二个元素存储在批处理文件内的 for 循环中?

即使在设置 EnableDelayedExpansion [重复] 之后,也无法在批处理文件中的 for 循环内设置变量值

在批处理文件的 for 循环中设置随机变量值会产生错误

转批处理命令 For循环命令详解!