Windows CMD - set within for loop is not working

前端 未结 2 482
谎友^
谎友^ 2020-12-19 17:14

I want to write batch file which will loop through all directories containing backup directory and remove files older than X days within it. On computer which I want run my

相关标签:
2条回答
  • 2020-12-19 17:36

    You need to use delayed expansion to read a variable that you have set inside a for loop.

    Try this instead

    setlocal enabledelayedexpansion
    rem we will memorize current directory
    pushd %cd%
    set folder="C:\Documents and Settings\myname\Desktop"
    cd %folder%
    rem loop only folders with five chars within their names (unfortunately on less also
    for /D %%g in (?????) DO (
        set checkpath="%cd%\%%g\backup"
        if exist !checkpath! (
            for %%a in ('%%g\backup\*.*') do (
            set FileDate=%%~ta
            set FileDate=!%FileDate:~0,10%!
            rem here I want to compare file modification data with current date
            )
        )
    popd
    pause
    

    Replacing the %'s with !'s on variables you have created will signal it to use delayed expansion instead.

    0 讨论(0)
  • 2020-12-19 17:50

    Bali's answer has a slight mistake. The second set filedate is incorrect, otherwise his is fine, but may not work if you do not have delayed expansion enabled. I fixed his mistake and showed you how to ensure delayed expansion is enabled. I have also made some other changes:

    ::This command will ensure that the delayed expansion, i.e. the "!"s below, 
    ::  will work.  Unfortunately, it also means you loose the results of any
    ::  "set" commands as soon as you execute the "endlocal" below.
    setlocal ENABLEDELAYEDEXPANSION
    
    ::you might want
    ::set "folder=%USERPROFILE%\Desktop"
    set "folder=C:\Documents and Settings\myname\Desktop"
    
    rem we will memorize current directory
    ::If you ran this code with the current directory set to a directory on
    ::a drive other than C:, your previous code would not have worked to
    :: change to your desired target directory.  this slight change fixes that.
    pushd "%folder%"
    
    rem loop only folders with five chars within their names - unfortunately on less also
    ::Use capitals for your loop variables.  The var names are case sensitive, and 
    ::using capitals ensures there is no confusion between the var names and ~modifiers
    for /D %%G in ( ????? ) DO (
        set checkpath="%CD%\%%G\backup"
        if exist !checkpath! (
            for %%A in ('%%G\backup\*.*') do (
                set FileDate=%%~tA
                set FileDate=!FileDate:~0,10!
                rem here I want to compare file modification data with current date
            )
    )
    popd
    endlocal
    pause
    

    But, you don't need the "setlocal" or delayed expansion if you write it like this:

    ::you might want
    ::set "folder=%USERPROFILE%\Desktop"
    set "folder=C:\Documents and Settings\myname\Desktop"
    
    rem we will memorize current directory
    ::If you ran this code with the current directory set to a directory on
    ::a drive other than C:, your previous code would not have worked to
    :: change to your desired target directory.  this slight change fixes that.
    pushd "%folder%"
    
    rem loop only folders with five chars within their names - unfortunately on less also
    for /D %%G in ( ????? ) DO (
        if exist "%%~G\backup" (
            for %%A in ('%%~G\backup\*.*') do (
                for /F "usebackq" %%T in ( '%%~tA' ) do (
                    echo File date is %%T, todays date is %DATE%
                )
            )
    )
    popd
    pause
    
    0 讨论(0)
提交回复
热议问题