【问题标题】:windows batch script: nested for loops not workingWindows批处理脚本:嵌套的for循环不起作用
【发布时间】:2016-07-31 16:14:59
【问题描述】:

我正在编写一个使用 robocopy 备份文件的 Windows 批处理脚本。我想模仿 linux rsync 的行为,默认情况下它将顶级源目录添加到目标路径。我不知道 robocopy 可以做到这一点,因为它只将源的子目录复制到目标。因此,我使用以下脚本从路径中提取顶级目录,以使用两个嵌套的 for 循环将其添加到目标路径。

我简化了下面的脚本以专注于不工作的部分。

@echo off
setlocal enabledelayedexpansion 

set source[0]=C:\Users\Sample User\Documents\keys
set source[1]=C:\Users\Sample User\Documents\Custom Office Templates

set dest=C:\Users\Sample User\Documents\test

:: range in for loop specified as (start,step,end)
for /l %%x in (0,1,1) do (
  for %%a in ("!source[%%x]!") do (
    set ddir=%%~nxa
  )
  echo "!source[%%x]!" "%dest%\%ddir%"
)

脚本产生以下输出:

"C:\Users\Sample User\Documents\keys" "C:\Users\Sample User\Documents\test\"
"C:\Users\Sample User\Documents\Custom Office Templates" "C:\Users\Sample User\Documents\test\"

%ddir% 变量为空。因此,源路径的顶级目录没有按我的意图添加到目标。我想实现以下输出:

"C:\Users\Sample User\Documents\keys" "C:\Users\Sample User\Documents\test\keys"
"C:\Users\Sample User\Documents\Custom Office Templates" "C:\Users\Sample User\Documents\test\Custom Office Templates"

我分别测试了外部和内部 for 循环,然后部分脚本按预期工作。当然,在这种情况下,内部 for 循环无法访问整个源数组。

外部for循环:

@echo off
setlocal enabledelayedexpansion 

set source[0]=C:\Users\Sample User\Documents\keys
set source[1]=C:\Users\Sample User\Documents\Custom Office Templates

:: range in for loop specified as (start,step,end)
for /l %%x in (0,1,1) do (
  echo "!source[%%x]!"
)

输出:

"C:\Users\Sample User\Documents\keys"
"C:\Users\Sample User\Documents\Custom Office Templates"

内部for循环:

@echo off
setlocal enabledelayedexpansion 

set source[0]=C:\Users\Sample User\Documents\keys
set dest=C:\Users\Sample User\Documents\test

for %%a in ("!source[0]!") do (
  set ddir=%%~nxa
)

输出:

"C:\Users\Sample User\Documents\keys" "C:\Users\Sample User\Documents\test\keys"

知道嵌套的 for 循环有什么问题吗?

【问题讨论】:

  • 您还需要在echo 命令行中对变量ddir 使用延迟扩展...
  • The %ddir% variable is empty. 因为您需要使用 !ddir! 和 enabledelayedexpansion。
  • 谢谢。现在它起作用了。我想我还没有真正理解 Windows 脚本的“延迟扩展”概念......
  • 一开始变量在读取行时被扩展(括号将多行合二为一)。许多脚本依赖于这种原始行为。当 IBM 的工程师(CMD 来自的 OS/2 是一个联合 MS/IBM 项目)增强命令提示时,他们使运行时扩展成为可能(即使用变量时)。要保持与现有脚本的兼容性,您必须将其打开。

标签: windows variables batch-file for-loop


【解决方案1】:

您需要正确使用延迟扩展变量和路径参数扩展。试试这个,让我知道任何问题:

@echo off
setlocal enabledelayedexpansion 

set "source[0]=C:\Users\Sample User\Documents\keys"
set "source[1]=C:\Users\Sample User\Documents\Custom Office Templates"
set "dest=C:\Users\Sample User\Documents\test"

:: range in for loop specified as (start,step,end)
for /l %%x in (0,1,1) do (
  for /f %%a in ("!source[%%x]!") do (
    set "ddir=%%~na" & set "dst=%dest%\!ddir!"
    echo "!source[%%x]!" "!dst!" ))
exit /b

【讨论】:

  • @Pohl7534 如果脚本适合您,请考虑通过单击答案左侧的“向上箭头”和“选择”标志来投票并接受此线程中的任何答案。 :)
  • 如果我从内部 for 循环中删除 /f 开关,您的建议将有效。正如@TessellatingHeckle 已经指出的那样,原始脚本中所有需要更改的地方是对!ddir! 变量使用delayedexpansion。
  • 评论不允许正确的谷歌搜索。要找到答案,它们必须作为答案发布,而不是 cmets。
猜你喜欢
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多