简体   繁体   中英

windows batch script: nested for loops not working

I am writing a windows batch script which uses robocopy to backup files. I want to mimic the behaviour of linux rsync, which by default adds the top level source directory to the destination path. I am not aware that robocopy can do this as it copies only the subdirectories of the source to the destination. Therefore I am using the following script to extract the top level directory from the path to add it to the destination path using two nested for loops.

I simplified the script below to focus on the part which is not working.

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

The script produces the following output:

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

The %ddir% variable is empty. Therefore the top level directory of the source path is not added to the destination as I intend. I would like to achieve the following output:

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

I tested the outer and inner for loops separately and then the partial scripts work as expected. Of course the inner for loop cannot access the whole source array in this case.

Outer for loop:

@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]!"
)

Output:

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

Inner for loop:

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

Output:

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

Any ideas what is wrong with the nested for loops?

You need to use delayed expansion of variables and path arguments expansion correctly. Try this and let me know any issues:

@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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM