Search code examples
batch-filerobocopy

How to pass a spaced path from robocopy output to a batch file?


I'm using the following script which outputs from robocopy all file names (with full paths) and their creation dates located in "H:\Backup" folder and if the total size of all files exceeds 100GB it deletes the oldest file.

REM @echo off

set "targetFolder=H:\Backup"
set "folderMaxSize=100"

for /f "tokens=2,*" %%a in ('
robocopy "%targetFolder%" "%targetFolder%" /l /nocopy /is /s /njh /njs /ndl /nc /ns /ts
^| sort
') do call :process_dir %%b
goto :eof

:process_dir


set "PREVB="
for /F "tokens=3" %%B in ('
dir /S /-C "%targetFolder%"
') do (
call set "BYTES=%%PREVB%%"
set "PREVB=%%B"
)
set "BYTES_GIGA=%BYTES:~,-9%"
set "BYTES_ONES=%BYTES:~-9%"
if not defined BYTES_GIGA set "BYTES_GIGA=0"
set /A "BYTES_ONES=1%BYTES_ONES%%%1000000000"
if %BYTES_ONES% GTR 0 set /A "BYTES_GIGA+=1"


if %BYTES_GIGA% GTR %folderMaxSize% (
echo "%targetFolder%" - size %BYTES_GIGA% GB, deleting oldest file: %1
del %1
) else (
echo "%targetFolder%" - size is less than %folderMaxSize% GB. No action needed.
exit
)

goto :eof

This code work flawlessly if there is no spaces in the path. The problem begins when the path to the file has a spacebar, f.e. "H:\Backup\Data\Folder Name\file123.dat" in that case I get "set "PREVB=H:\Backup\Data\Folder".

Any suggestions will be appreciated.


Solution

  • See this example:

    set s=v w x y z
    
    for /F %%a in ("%s%") do echo %%a
    
    [OUTPUT]
    v w x y z
    

    when you use for /f and assign a variable (say %%a) the whole input is assigned to your variable.

    Using "tokens=..." you can split your input and assign every space-delimited* part to a different variable:

    for /F "tokens=1,2,3,4,5" %%a in ("%s%") do echo %%a,%%b,%%c,%%d,%%e
    
    [OUTPUT]
    v,w,x,y,z
    

    *(different delimiters can be specified using delims)

    you can also skip some token:

    for /F "tokens=2,4" %%a in ("%s%") do echo %%a,%%b
    
    [OUTPUT]
    w,y
    

    Using * you can assign remaining tokens to a single variable:

    for /F "tokens=2,*" %%a in ("%s%") do echo %%a,%%b
    
    [OUTPUT]
    w,x y z
    

    In this last example token 1 is ignored, token 2 is assigned to %%a and the remaining part of the input string is assigned to %%b.

    In your situation:

    set s=                         2022/11/27 08:50:05    D:\te mp\123.txt
    
    for /F "tokens=2,*" %%a in ("%s%") do set "PREVB=%%b"
    echo %prevb%
    
    [OUTPUT]
    D:\te mp\123.txt
    

    In this example token 1 is ignored, token 2 (time value) - that is: the last token before the content you need - is assigned to %%a and the remaining part of the input to %%b.