Monday, April 11, 2011

write a batch file to remove the folders by date and time wise

Exact Duplicates:

I have a folder named 'dump' on a sever on a network. Every day lot of temp files and folders will be saved in that folder.

I want to delete those files and sub folders. The condition is that I want to delete one hour before files & folders only i.e one our before the current time when we are running the batch file.

This means I want to keep one our files in that folder to run the other ACTIVITIES. like this current time.

  1. go to folder and list the files as time wise
  2. get the current time
  3. delete the files which were 1 hour older than current time
From stackoverflow
  • The only way I know that I know that what you are trying to do might be possible is using the for command and the ~t expanding parameter.

    for %r in (*.*) DO echo %r "created on" %~tr
    

    That produces:

    C:\>echo BOOTSECT.BAK "created on" 2009/02/17 11:59 PM
    BOOTSECT.BAK "created on" 2009/02/17 11:59 PM
    
    C:\>echo config.sys "created on" 2006/09/18 11:43 PM
    config.sys "created on" 2006/09/18 11:43 PM
    

    I think a more likely scenario would involve using windows scripting host, or powershell, but you did not mention that those are options for you, so I am assuming that there is a good reason, for not being able to use those technologies.

  • I think you are better off using PowerShell or WSH (as Rihan Meij mentioned) in this case. Comparing data and time is possible but very brittle (as there is no way to get a data/time in batch culturally-neutral). You might write something like this:

    setlocal enableextensions
    set Now=%date%
    set NowTime=%time:~0,-3%
    call :tokenize_date %Now%
    call :tokenize_time %NowTime%
    echo %YEAR%-%MONTH%-%DAY%T%HOUR%:%MINUTE%:%SECOND%
    call :one_hour_before %Now% %NowTime%
    echo %RESULT_DATE% %RESULT_TIME%
    ping -n 1 -w 1500 ::1>NUL
    set Now2=%date%
    set NowTime2=%time:~0,-3%
    call :date_time_compare %Now% %NowTime% %Now2% %NowTime2%
    echo %Now%T%NowTime% compared to %Now2%T%NowTime2%: %RESULT%
    endlocal
    goto :eof
    
    :tokenize_date
        rem assuming ISO 8601 date format YYYY-MM-DD
        setlocal enableextensions
        set arg=%1
        set YEAR=%arg:~0,4%
        set MONTH=%arg:~5,2%
        set DAY=%arg:~8,2%
        endlocal&set YEAR=%YEAR%&set MONTH=%MONTH%&set DAY=%DAY%
    goto :eof
    
    :tokenize_time
        rem assuming ISO-8601 time format HH:MM:SS, 24-hour
        setlocal enableextensions
        set arg=%1
        set HOUR=%arg:~0,2%
        set MINUTE=%arg:~3,2%
        set SECOND=%arg:~6,2%
        endlocal&set HOUR=%HOUR%&set MINUTE=%MINUTE%&set SECOND=%SECOND%
    goto :eof
    
    :one_hour_before
        rem gets a date as %1 and a time as %2
        rem returns a date in RESULT_DATE and a time in RESULT_TIME
        setlocal enabledelayedexpansion enableextensions
        set months=31 28 31 30 31 30 31 31 30 31 30 31
        set i=0
        for %%x in (%months%) do (
            set /a i+=1
            set month_length_!i!=%%x
        )
        call :tokenize_date %1
        call :tokenize_time %2
        set /a HOUR-=1
        if %HOUR% LSS 0 (
            set /a DAY-=1
            set /a HOUR+=24
            if %DAY% LSS 0 (
                set /a MONTH-=1
                if %MONTH% LSS 0 (
                    set /a YEAR-=1
                    set /a MONTH+=12
                )
                set /a DAY+=month_length_!MONTH!
            )
        )
        endlocal&set RESULT_DATE=%YEAR%-%MONTH%-%DAY%&set RESULT_TIME=%HOUR%:%MINUTE%:%SECOND%
    goto :eof
    
    :date_time_compare
        rem expects %1 - date 1, %2 - time 1, %3 - date 2, %4 - time 2
        rem returns a value < 0 if datetime1 is earlier than datetime2
        rem                 > 0                 later than
        rem                 = 0                 equal to
        rem the return value is saved in the variable %RETURN%
        setlocal enableextensions
        call :tokenize_date %3
        call :tokenize_time %4
        set YEAR2=%YEAR%
        set MONTH2=%MONTH%
        set DAY2=%DAY%
        set HOUR2=%HOUR%
        set MINUTE2=%MINUTE%
        set SECOND2=%SECOND%
        call :tokenize_date %1
        call :tokenize_time %2
        if %YEAR2% GTR %YEAR% (endlocal&set RESULT=-1&goto :eof) else (
            if %YEAR2% LSS %YEAR% (endlocal&set RESULT=1&goto :eof) else (
                if %MONTH2%%DAY2%%HOUR2%%MINUTE2%%SECOND2% GTR %MONTH%%DAY%%HOUR%%MINUTE%%SECOND% (
                    endlocal&set RESULT=-1&goto :eof
                ) else (
                    if %MONTH2%%DAY2%%HOUR2%%MINUTE2%%SECOND2%==%MONTH%%DAY%%HOUR%%MINUTE%%SECOND% (
                        endlocal&set RESULT=0&goto :eof
                    ) else (
                        endlocal&set RESULT=1&goto :eof
                    )
                )
            )
        )
    goto :eof
    

    Sorry, it has gotten a bit long. Comparing date/time has only partially been tested right now, but should work. Careful with the time when it contains sub-seconds, since those introduce a comma here, which disturbs the argument order for called subroutines (hence the %time:~0,-3% to avoid that).

    After that you can use the %~tI expansion to get a date and a time, compare them to current minus one hour and delete if applicable.

    Note 1: I am assuming ISO 8601 date and time formats with 24 hours, which is what I am using here. For non-standard date formats you would have to alter the subroutines a bit (but 12 hour time would probably be a pain).

    Note 2: The code doesn't care about leap years, currently. Would be another 5 or 6 lines of code in :one_hour_before, I think.

0 comments:

Post a Comment