Batch file to delete files and folder

2019-07-19 06:22发布

I am looking for a way of deleting files that are contained in a folder with a specific name and then delete that folder afterwards.

I know there there is the forfiles command line that I can use to delete the files, I just don't know how to get the folder name into the path. The folder is named based on the date that it was created and I want to delete the folder that is 7 days old. The folder is formatted as yyyymmdd.

basically I need

forfiles /P "C:\backups\[DATE 7 DAYS AGO IN yyyymmdd format]" /S /M *.BAK /C "cmd /c del @path"

and then I think to delete the folder after it would be

forfiles /P "C:\backups\[DATE 7 DAYS AGO IN yyyymmdd format]" /S /C "cmd /c IF @isDir == TRUE rd @path"

How do I fill in the [DATE 7 DAYS AGO ...] for these.

3条回答
Evening l夕情丶
2楼-- · 2019-07-19 06:50

Alright so I followed Elektro Hacker's advice and I ended up doing this via powershell, which looks as follows:

$currentDate = get-date
$backupPath = "C:\backup\"
$logFilePath = ("$backupPath" + "ScriptAndQuery\Logs\")

$dailyLog = ("$logFilePath" + "daily_delete.txt")
$weeklyLog = ("$logFilePath" + "weekly_delete.txt")
$monthlyLog = ("$logFilePath" + "monthly_delete.txt")

$dailyBackup = ("$backupPath" + "Daily\")
$weeklyBackup = ("$backupPath" + "Weekly\")
$monthlyBackup = ("$backupPath" + "Monthly\")

$addDateToFile = "TRUE"

get-childitem $dailyBackup |? { $_.psiscontainer -and $_.lastwritetime -le ($currentDate).adddays(-7) } |% { 
    try {
        if($addDateToFile -eq "TRUE") {
            Add-Content "$dailyLog" "$currentDate`r`n"
            $addDateToFile = "FALSE"
        }

        $fullPath = $_.FullName
        remove-item $fullPath -Recurse -force

        if (test-path $fullPath) {
            Add-Content "$dailyLog" "FAILED TO DELETE $fullPath`n"
        } else {
            Add-Content "$dailyLog" "SUCCESSFULLY DELETED $fullPath`n"
        }
    }
    catch {
        Add-Content "$dailyLog" "Exception Occurred: $_.Exception`n"
    }
}

if ($addDateToFile -eq "FALSE") {
    Add-Content "$dailyLog" "`r`n"
    $addDateToFile = "TRUE"
}

get-childitem $weeklyBackup |? {$_.psiscontainer -and $_.lastwritetime -le ($currentDate).adddays(-28)} |% { 
    try {
        if ($addDateToFile -eq "TRUE") {
            Add-Content "$weeklyLog" "$currentDate`r`n"
            $addDateToFile = "FALSE"
        }

        $fullPath = $_.FullName
        remove-item $fullPath -Recurse -force

        if (test-path $fullPath) {
            Add-Content "$weeklyLog" "FAILED TO DELETE $fullPath`n"
        } else {
            Add-Content "$weeklyLog" "SUCCESSFULLY DELETED $fullPath`n"
        }
    }
    catch {
        Add-Content "$weeklyLog" "Exception Occurred: $_.Exception`n"
    }
}

if ($addDateToFile -eq "FALSE") {
    Add-Content "$weeklyLog" "`r`n"
    $addDateToFile = "TRUE"
}

get-childitem $monthlyBackup |? {$_.psiscontainer -and $_.lastwritetime -le ($currentDate).adddays(-365)} |% { 
    try {
        if($addDateToFile -eq "TRUE") {
            Add-Content "$monthlyLog" "$currentDate`r`n"
            $addDateToFile = "FALSE"
        }

        $fullPath = $_.FullName
        remove-item $fullPath -Recurse -force 

        if (test-path $fullPath) {
            Add-Content "$monthlyLog" "FAILED TO DELETE $fullPath`n"
        } else {
            Add-Content "$monthlyLog" "SUCCESSFULLY DELETED $fullPath`n"
        }
    }
    catch {
        Add-Content "$monthlyLog" "Exception Occurred: $_.Exception`n"
    }
} 

if ($addDateToFile -eq "FALSE") {
    Add-Content "$monthlyLog" "`r`n"
}

In this I have 3 different backups that occur (daily, weekly, and monthly). So basically I delete all the files from daily that are a week old, weekly that are a month old and monthly that are a year old. I also print to a file the date and folder that was removed for each, or a failure message in the event that the folder still exists or and exception has occurred. This script is then run daily and is working great so far.

Thanks, DMan

查看更多
戒情不戒烟
3楼-- · 2019-07-19 06:53

Try using rmdir (at the command prompt type rmdir /? for help)

查看更多
Bombasti
4楼-- · 2019-07-19 06:54

1st - why you try to delete first the files, and next the tolfer? If you delete the folder first you are doing the same thing in less time...

2nd - I THINK You can't do that in Batch, not without errors, you need to extract (know) the calendar days for at least the "X" years you need to use in your purposes, and Batch don't have any way to extract that info, or to be a math genious to know how to take the calendar dates of past years.

so you need a realistic scripting language who can acces to the Microsoft.Time and data library and do the comparision. (Ruby, Python, Perl, all what you want less Batch)

By the way exist some ultra advanced aricmetics batfile codes wrote by RobVanDeerWoud to "play" with things, for example with this script you can add "X" days to a date, take a look to see if you can modify to deduct days:

(CREDITS FOR THE AUTHOR OF CODE: ROBVANDERWOUD)

DATEADD.BAT:



@ECHO OFF
ECHO.

:: Check the Windows version
IF NOT "%OS%"=="Windows_NT" GOTO Syntax
SETLOCAL

:: Initialize variable
SET Error=0

:: Check the command line arguments
IF     "%~1"=="" GOTO Syntax
IF NOT "%~3"=="" GOTO Syntax
IF "%~2"=="" (
    FOR %%A IN (%Date%) DO SET cDate=%%A
    SET cDays=%~1
) ELSE (
    SET cDate=%~1
    SET cDays=%~2
)

:: Read the Date format from the registry
CALL :ReadDateFormat

:: Check if a valid date was specified
(ECHO.%cDate%) | FINDSTR /R /B /C:"[0-9]*\%sDate%[0-9]*\%sDate%[0-9]*" >NUL
IF ERRORLEVEL 1 (
    ECHO Error: %cDate% is not a valid date
    ECHO.
    GOTO Syntax
)

:: Check if the second argument is a valid number
(ECHO.%cDays%) | FINDSTR /R /B /C:"-*[0-9]*" >NUL
IF ERRORLEVEL 1 (
    ECHO Error: %cDays% is not an integer
    ECHO.
    GOTO Syntax
)

:: Parse the date specified
CALL :ParseDate %cDate%

:: Check for errors
IF %Error% NEQ 0 GOTO Syntax

:: Convert the parsed Gregorian date to Julian
CALL :JDate %GYear% %GMonth% %GDay%

:: Display original input
ECHO Starting date   : %cDate%

:: Add or subtract the specified number of days
IF "%cDays:~0,1%"=="-" (
    SET /A NewJDate = %JDate% - %cDays:~1%
    ECHO Days subtracted : %cDays:~1%
) ELSE (
    SET /A NewJDate = %JDate% + %cDays%
    ECHO Days added      : %cDays%
)

:: Convert the new Julian date back to Gregorian again
CALL :GDate %NewJDate%

:: Reformat the date to local format
CALL :ReformatDate %GDate%

:: Display the result
ECHO Resulting date  : %LDate%

:: Return the result in a variable named after this batch file
ENDLOCAL & SET %~n0=%LDate%
GOTO:EOF


::===================================::
::                                   ::
::   -   S u b r o u t i n e s   -   ::
::                                   ::
::===================================::


:GDate
:: Convert Julian date back to "normal" Gregorian date
:: Argument : Julian date
:: Returns  : YYYY MM DD
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
::
SET /A P      = %1 + 68569
SET /A Q      = 4 * %P% / 146097
SET /A R      = %P% - ( 146097 * %Q% +3 ) / 4
SET /A S      = 4000 * ( %R% + 1 ) / 1461001
SET /A T      = %R% - 1461 * %S% / 4 + 31
SET /A U      = 80 * %T% / 2447
SET /A V      = %U% / 11
SET /A GYear  = 100 * ( %Q% - 49 ) + %S% + %V%
SET /A GMonth = %U% + 2 - 12 * %V%
SET /A GDay   = %T% - 2447 * %U% / 80
:: Clean up the mess
FOR %%A IN (P Q R S T U V) DO SET %%A=
:: Add leading zeroes
IF 1%GMonth% LSS 20 SET GMonth=0%GMonth%
IF 1%GDay%   LSS 20 SET GDay=0%GDay%
:: Return value
SET GDate=%GYear% %GMonth% %GDay%
GOTO:EOF


:JDate
:: Convert date to Julian
:: Arguments : YYYY MM DD
:: Returns   : Julian date
::
:: First strip leading zeroes
SET MM=%2
SET DD=%3
IF %MM:~0,1% EQU 0 SET MM=%MM:~1%
IF %DD:~0,1% EQU 0 SET DD=%DD:~1%
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
SET /A Month1 = ( %MM% - 14 ) / 12
SET /A Year1  = %1 + 4800
SET /A JDate  = 1461 * ( %Year1% + %Month1% ) / 4 + 367 * ( %MM% - 2 -12 * %Month1% ) / 12 - ( 3 * ( ( %Year1% + %Month1% + 100 ) / 100 ) ) / 4 + %DD% - 32075
FOR %%A IN (Month1 Year1) DO SET %%A=
GOTO:EOF 


:ParseDate
:: Parse (Gregorian) date depending on registry's date format settings
:: Argument : Gregorian date in local date format,
:: Requires : sDate (local date separator), iDate (local date format number)
:: Returns  : GYear (4-digit year), GMonth (2-digit month), GDay (2-digit day)
::
IF %iDate%==0 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%1') DO (
    SET GYear=%%C
    SET GMonth=%%A
    SET GDay=%%B
)
IF %iDate%==1 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%1') DO (
    SET GYear=%%C
    SET GMonth=%%B
    SET GDay=%%A
)
IF %iDate%==2 FOR /F "TOKENS=1-3 DELIMS=%sDate%" %%A IN ('ECHO.%1') DO (
    SET GYear=%%A
    SET GMonth=%%B
    SET GDay=%%C
)
IF %GDay%   GTR 31 SET Error=1
IF %GMonth% GTR 12 SET Error=1
GOTO:EOF


:ReadDateFormat
:: Read the Date format from the registry.
:: Arguments : none
:: Returns   : sDate (separator), iDate (date format number)
::
:: First, export registry settings to a temporary file:
START /W REGEDIT /E "%TEMP%.\_TEMP.REG" "HKEY_CURRENT_USER\Control Panel\International"
:: Now, read the exported data:
FOR /F "tokens=1* delims==" %%A IN ('TYPE "%TEMP%.\_TEMP.REG" ˆ| FIND /I "iDate"') DO SET iDate=%%B
FOR /F "tokens=1* delims==" %%A IN ('TYPE "%TEMP%.\_TEMP.REG" ˆ| FIND /I "sDate"') DO SET sDate=%%B
:: Remove the temporary file:
DEL "%TEMP%.\_TEMP.REG"
:: Remove quotes from the data read:
:: SET iDate=%iDate:"=%
FOR %%A IN (%iDate%) DO SET iDate=%%~A
:: SET sDate=%sDate:"=%
FOR %%A IN (%sDate%) DO SET sDate=%%~A
GOTO:EOF


:ReformatDate
:: Reformat the date back to the local format
:: Arguments : YYYY MM DD
:: Returns   : LDate (Gregorian date in local format)
::
IF %iDate%==0 SET LDate=%2%sDate%%3%sDate%%1
IF %iDate%==1 SET LDate=%3%sDate%%2%sDate%%1
IF %iDate%==2 SET LDate=%1%sDate%%2%sDate%%3
GOTO:EOF


:Syntax
ECHO DateAdd.bat,  Version 1.10 for Windows NT 4 / 2000 / XP / Server 2003 / Vista
ECHO Add (or subtract) the specified number of days to (or from) the specified date
ECHO.
ECHO Usage:  DATEADD  [ date ]  days
ECHO.
ECHO Where:  "date"   is a "normal" Gregorian date in the local computer's format
ECHO                  (default value if no date is specified: today's date)
ECHO         "days"   is the number of days to add or subtract
ECHO.
IF     "%OS%"=="Windows_NT" FOR %%A IN (%Date%) DO SET Today=%%A
IF     "%OS%"=="Windows_NT" ECHO E.g.    DATEADD %Today%  1 will return tomorrow's date  (as will DATEADD  1)
IF     "%OS%"=="Windows_NT" ECHO         DATEADD %Today% -1 will return yesterday's date (as will DATEADD -1)
IF     "%OS%"=="Windows_NT" ENDLOCAL
IF NOT "%OS%"=="Windows_NT" ECHO E.g.    DATEADD 01/25/2007  1 should return 01/26/2007
IF NOT "%OS%"=="Windows_NT" ECHO         DATEADD 01/25/2007 -1 should return 01/24/2007
ECHO.
ECHO Julian date conversion based on Fliegel-Van Flandern algorithms from
ECHO the Astronomical Almanac, provided by Doctor Fenton on the Math Forum
ECHO (http://mathforum.org/library/drmath/view/51907.html), and converted
ECHO to batch code by Ron Bakowski.
ECHO.
ECHO Written by Rob van der Woude
ECHO http://www.robvanderwoude.com 
查看更多
登录 后发表回答