windows批处理脚本:嵌套for循环不起作用

时间:2016-07-31 16:15:00

标签: windows variables batch-file for-loop

我正在编写一个使用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循环不能访问整个源数组。

外循环:

@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"

内部循环:

@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循环有什么问题?

1 个答案:

答案 0 :(得分:0)

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

@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