Question

Je cherche un moyen de supprimer tous les fichiers datant de plus de 7 jours dans un fichier batch.J'ai cherché sur le Web et trouvé des exemples contenant des centaines de lignes de code et d'autres nécessitant l'installation d'utilitaires de ligne de commande supplémentaires pour accomplir la tâche.

Des choses similaires peuvent être fait en BASH en seulement quelques lignes de code.Il semble que quelque chose d'au moins simple puisse être fait pour les fichiers batch sous Windows.Je recherche une solution qui fonctionne dans une invite de commande Windows standard, sans aucun utilitaire supplémentaire.S'il vous plaît, pas de PowerShell ou de Cygwin non plus.

Était-ce utile?

La solution

Apprécier:

forfiles -p "C:\what\ever" -s -m *.* -d <number of days> -c "cmd /c del @path"

Voir documentation du fichier pour plus de détails.

Pour plus de cadeaux, reportez-vous à Un index A-Z de la ligne de commande Windows XP.

Si vous n'avez pas forfiles installé sur votre ordinateur, copiez-le depuis n'importe quel Windows Serveur 2003 sur votre ordinateur Windows XP à l'adresse %WinDir%\system32\.Cela est possible puisque le fichier EXE est entièrement compatible entre Windows Server 2003 et Windows XP.

Les versions ultérieures de Windows et Windows Server l'ont installé par défaut.

Pour Windows 7 et versions ultérieures (y compris Windows 10) :

La syntaxe a un peu changé.La commande mise à jour est donc :

forfiles /p "C:\what\ever" /s /m *.* /D -<number of days> /C "cmd /c del @path"

Autres conseils

Exécutez ce qui suit commandes:

ROBOCOPY C:\source C:\destination /mov /minage:7
del C:\destination /q

Déplacez tous les fichiers (en utilisant /mov, qui déplace les fichiers puis les supprime par opposition à /move qui déplace des arborescences de fichiers entières qui sont ensuite supprimées) via robocopy vers un autre emplacement, puis exécutez une commande de suppression sur ce chemin et vous êtes tous bien.

De plus, si vous avez un répertoire contenant beaucoup de données, vous pouvez utiliser /mir changer

Ok, je m'ennuyais un peu et j'ai trouvé ceci, qui contient ma version du remplacement de l'époque Linux d'un pauvre homme limité pour un usage quotidien (pas de rétention de temps) :

7daysclean.cmd

@echo off
setlocal ENABLEDELAYEDEXPANSION
set day=86400
set /a year=day*365
set /a strip=day*7
set dSource=C:\temp

call :epoch %date%
set /a slice=epoch-strip

for /f "delims=" %%f in ('dir /a-d-h-s /b /s %dSource%') do (
    call :epoch %%~tf
    if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)
)
exit /b 0

rem Args[1]: Year-Month-Day
:epoch
    setlocal ENABLEDELAYEDEXPANSION
    for /f "tokens=1,2,3 delims=-" %%d in ('echo %1') do set Years=%%d& set Months=%%e& set Days=%%f
    if "!Months:~0,1!"=="0" set Months=!Months:~1,1!
    if "!Days:~0,1!"=="0" set Days=!Days:~1,1!
    set /a Days=Days*day
    set /a _months=0
    set i=1&& for %%m in (31 28 31 30 31 30 31 31 30 31 30 31) do if !i! LSS !Months! (set /a _months=!_months! + %%m*day&& set /a i+=1)
    set /a Months=!_months!
    set /a Years=(Years-1970)*year
    set /a Epoch=Years+Months+Days
    endlocal& set Epoch=%Epoch%
    exit /b 0

USAGE

set /a strip=day*7 :Changement 7 pour le nombre de jours à conserver.

set dSource=C:\temp :Il s'agit du répertoire de départ pour rechercher les fichiers.

REMARQUES

C'est du code non destructif, il affichera ce qui se serait passé.

Changement :

if !epoch! LEQ %slice% (echo DELETE %%f ^(%%~tf^)) ELSE echo keep %%f ^(%%~tf^)

à quelque chose comme :

if !epoch! LEQ %slice% del /f %%f

donc les fichiers sont réellement supprimés

Février:est codé en dur sur 28 jours.Les années bissextiles, c'est vraiment un enfer à ajouter.si quelqu'un a une idée qui n'ajouterait pas 10 lignes de code, allez-y et publiez-la pour que je l'ajoute à mon code.

époque:Je n'ai pas pris en compte le temps, car il est nécessaire de supprimer des fichiers plus anciens qu'une certaine date, prendre des heures/minutes aurait supprimé les fichiers d'une journée censée être conservée.

LIMITATION

époque prend pour acquis que votre format de date courte est AAAA-MM-JJ.Il devrait être adapté pour d'autres paramètres ou une évaluation au moment de l'exécution (lire sShortTime, configuration liée à l'utilisateur, configurer l'ordre approprié des champs dans un filtre et utiliser le filtre pour extraire les données correctes de l'argument).

Ai-je mentionné que je déteste le formatage automatique de cet éditeur ?ça supprime les lignes vides et le copier-coller est un enfer.

J'espère que ça aide.

forfiles /p "v:" /s /m *.* /d -3 /c "cmd /c del @path"

Tu devrais faire /d -3 (3 jours plus tôt) Cela fonctionne bien pour moi.Tous les lots compliqués pourraient donc se retrouver à la poubelle.Aussi forfiles ne prennent pas en charge les chemins UNC, établissez donc une connexion réseau à un lecteur spécifique.

Jetez un oeil à mon répondre à un question similaire:

REM del_old.bat
REM usage: del_old MM-DD-YYY
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do if exist %%~nxa echo %%~nxa >> FILES_TO_KEEP.TXT
for /f "tokens=*" %%a IN ('xcopy *.* /L /I /EXCLUDE:FILES_TO_KEEP.TXT null') do if exist "%%~nxa" del "%%~nxa"

Cela supprime les fichiers plus anciens qu'une date donnée.Je suis sûr qu'il peut être modifié pour revenir sept jours en arrière à partir de la date actuelle.

mise à jour: Je remarque que HerbCSO a amélioré le script ci-dessus.Je recommande d'utiliser sa version plutôt.

Ma commande est

forfiles -p "d:\logs" -s -m*.log -d-15 -c"cmd /c del @PATH\@FILE" 

@PATH - c'est juste un chemin dans mon cas, j'ai donc dû utiliser @PATH\@FILE

aussi forfiles /? ça ne marche pas pour moi aussi, mais forfiles (sans "?") a bien fonctionné.

Et la seule question que je me pose :comment ajouter plusieurs masques (par exemple ".log|.bak") ?

Tout cela concernant forfiles.exe que je téléchargé ici (sur Win XP)

Mais si vous utilisez le serveur Windows, forfiles.exe devrait déjà être là et il diffère de la version FTP.C'est pourquoi je devrais modifier la commande.

Pour Windows Server 2003, j'utilise cette commande :

forfiles -p "d:\Backup" -s -m *.log -d -15 -c "cmd /c del @PATH"

Pour Windows Serveur 2008 R2 :

forfiles /P c:\sql_backups\ /S /M *.sql /D -90 /C "cmd /c del @PATH"

Cela supprimera tout .sql fichiers plus anciens que 90 jours.

Copiez ce code et enregistrez-le sous DelOldFiles.vbs.

UTILISATION UNIQUEMENT DANS L'INVITÉ DE COMMANDE :cscript DelOldFiles.vbs 15

15 signifie supprimer les fichiers datant de plus de 15 jours.

  'copy from here
    Function DeleteOlderFiles(whichfolder)
       Dim fso, f, f1, fc, n, ThresholdDate
       Set fso = CreateObject("Scripting.FileSystemObject")
       Set f = fso.GetFolder(whichfolder)
       Set fc = f.Files
       Set objArgs = WScript.Arguments
       n = 0
       If objArgs.Count=0 Then
           howmuchdaysinpast = 0
       Else
           howmuchdaysinpast = -objArgs(0)
       End If
       ThresholdDate = DateAdd("d", howmuchdaysinpast, Date)   
       For Each f1 in fc
     If f1.DateLastModified<ThresholdDate Then
        Wscript.StdOut.WriteLine f1
        f1.Delete
        n = n + 1    
     End If
       Next
       Wscript.StdOut.WriteLine "Deleted " & n & " file(s)."
    End Function

    If Not WScript.FullName = WScript.Path & "\cscript.exe" Then
      WScript.Echo "USAGE ONLY IN COMMAND PROMPT: cscript DelOldFiles.vbs 15" & vbCrLf & "15 means to delete files older than 15 days in past."
      WScript.Quit 0   
    End If

    DeleteOlderFiles(".")
 'to here

Utilisez forfiles.

Il existe différentes versions.Les premiers utilisent des paramètres de style Unix.

Ma version (pour le serveur 2000 - notez qu'il n'y a pas d'espace après les commutateurs) -

forfiles -p"C:\what\ever" -s -m*.* -d<number of days> -c"cmd /c del @path"

Pour ajouter des fichiers forfiles à XP, récupérez l'exe depuis ftp://ftp.microsoft.com/ResKit/y2kfix/x86/

et ajoutez-le à C:\WINDOWS\system32

Pour Windows 2012 R2, les éléments suivants fonctionneraient :

    forfiles /p "c:\FOLDERpath" /d -30 /c "cmd /c del @path"

pour voir les fichiers qui seront supprimés, utilisez ceci

    forfiles /p "c:\FOLDERpath" /d -30 /c "cmd /c echo @path @fdate"

OMI, JavaScript devient progressivement un standard de script universel :il est probablement disponible dans plus de produits que tout autre langage de script (sous Windows, il est disponible à l'aide de Windows Scripting Host).Je dois nettoyer les anciens fichiers dans de nombreux dossiers, voici donc une fonction JavaScript pour ce faire :

// run from an administrator command prompt (or from task scheduler with full rights):  wscript jscript.js
// debug with:   wscript /d /x jscript.js

var fs = WScript.CreateObject("Scripting.FileSystemObject");

clearFolder('C:\\temp\\cleanup');

function clearFolder(folderPath)
{
    // calculate date 3 days ago
    var dateNow = new Date();
    var dateTest = new Date();
    dateTest.setDate(dateNow.getDate() - 3);

    var folder = fs.GetFolder(folderPath);
    var files = folder.Files;

    for( var it = new Enumerator(files); !it.atEnd(); it.moveNext() )
    {
        var file = it.item();

        if( file.DateLastModified < dateTest)
        {
            var filename = file.name;
            var ext = filename.split('.').pop().toLowerCase();

            if (ext != 'exe' && ext != 'dll')
            {
                file.Delete(true);
            }
        }
    }

    var subfolders = new Enumerator(folder.SubFolders);
    for (; !subfolders.atEnd(); subfolders.moveNext())
    {
        clearFolder(subfolders.item().Path);
    }
}

Pour chaque dossier à effacer, ajoutez simplement un autre appel à la fonction clearFolder().Ce code particulier préserve également les fichiers exe et dll et nettoie également les sous-dossiers.

Que diriez-vous de cette modification sur 7daysclean.cmd prendre en compte une année bissextile ?

Cela peut être fait en moins de 10 lignes de codage !

set /a Leap=0
if (Month GEQ 2 and ((Years%4 EQL 0 and Years%100 NEQ 0) or Years%400 EQL 0)) set /a Leap=day
set /a Months=!_months!+Leap

Edité par Mofi :

La condition ci-dessus contribuée par J.R. évalue toujours à FAUX à cause d'une syntaxe invalide.

Et Month GEQ 2 est également faux car l'ajout de 86 400 secondes pour un jour supplémentaire doit être effectué dans une année bissextile uniquement pour les mois de mars à décembre, mais pas pour février.

Un code fonctionnel pour prendre en compte les jours bissextiles - dans l'année en cours uniquement - dans un fichier batch 7daysclean.cmd posté par Geai serait:

set "LeapDaySecs=0"
if %Month% LEQ 2 goto CalcMonths
set /a "LeapRule=Years%%4"
if %LeapRule% NEQ 0 goto CalcMonths
rem The other 2 rules can be ignored up to year 2100.
set /A "LeapDaySecs=day"
:CalcMonths
set /a Months=!_months!+LeapDaySecs

Il y a très souvent des questions relatives à la date/heure à résoudre avec un fichier batch.Mais l'interpréteur de ligne de commande cmd.exe n'a aucune fonction pour les calculs de date/heure.De nombreuses solutions efficaces utilisant des applications de console ou des scripts supplémentaires ont déjà été publiées ici, sur d'autres pages de Stack Overflow et sur d'autres sites Web.

Il est courant pour les opérations basées sur la date/l’heure de convertir une chaîne de date/heure en secondes depuis un jour déterminé.Le 01/01/1970 00:00:00 UTC est très courant.Mais n’importe quel jour ultérieur pourrait également être utilisé en fonction de la plage de dates requise pour prendre en charge une tâche spécifique.

Geai posté 7daysclean.cmd contenant une solution rapide "date en secondes" pour l'interpréteur de ligne de commande cmd.exe.Mais cela ne prend pas en compte les années bissextiles. J.R. a posté un Ajouter sur pour prendre en compte les jours bissextiles de l'année en cours, mais en ignorant les autres années bissextiles depuis l'année de base, c'est-à-diredepuis 1970.

J'utilise depuis 20 ans des tables statiques (tableaux) créées une fois avec une petite fonction C pour obtenir rapidement le nombre de jours y compris les jours bissextiles à partir du 01/01/1970 dans les fonctions de conversion date/heure dans mes applications écrites en C/C++.

Cette méthode de table très rapide peut également être utilisée dans le code batch en utilisant POUR commande.J'ai donc décidé de coder le sous-programme batch GetSeconds qui calcule le nombre de secondes depuis le 01/01/1970 00:00:00 UTC pour une chaîne date/heure transmise à cette routine.

Note: Les secondes intercalaires ne sont pas prises en compte car les systèmes de fichiers Windows ne prennent pas non plus en charge les secondes intercalaires.

Tout d'abord, les tableaux :

  1. Jours depuis le 01/01/1970 00:00:00 UTC pour chaque année, y compris les jours bissextiles.

    1970 - 1979:     0   365   730  1096  1461  1826  2191  2557  2922  3287
    1980 - 1989:  3652  4018  4383  4748  5113  5479  5844  6209  6574  6940
    1990 - 1999:  7305  7670  8035  8401  8766  9131  9496  9862 10227 10592
    2000 - 2009: 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245
    2010 - 2019: 14610 14975 15340 15706 16071 16436 16801 17167 17532 17897
    2020 - 2029: 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550
    2030 - 2039: 21915 22280 22645 23011 23376 23741 24106 24472 24837 25202
    2040 - 2049: 25567 25933 26298 26663 27028 27394 27759 28124 28489 28855
    2050 - 2059: 29220 29585 29950 30316 30681 31046 31411 31777 32142 32507
    2060 - 2069: 32872 33238 33603 33968 34333 34699 35064 35429 35794 36160
    2070 - 2079: 36525 36890 37255 37621 37986 38351 38716 39082 39447 39812
    2080 - 2089: 40177 40543 40908 41273 41638 42004 42369 42734 43099 43465
    2090 - 2099: 43830 44195 44560 44926 45291 45656 46021 46387 46752 47117
    2100 - 2106: 47482 47847 48212 48577 48942 49308 49673
    

    Le calcul des secondes pour les années 2039 à 2106 avec une époque commençant le 01/01/1970 n'est possible qu'en utilisant une variable non signée de 32 bits, c'est-à-direunsigned long (ou unsigned int) en C/C++.

    Mais cmd.exe utiliser pour les expressions mathématiques une variable signée de 32 bits.Par conséquent, la valeur maximale est 2147483647 (0x7FFFFFFF), soit 2038-01-19 03:14:07.

  2. Informations sur les années bissextiles (Non/Oui) pour les années 1970 à 2106.

    1970 - 1989: N N Y N N N Y N N N Y N N N Y N N N Y N
    1990 - 2009: N N Y N N N Y N N N Y N N N Y N N N Y N
    2010 - 2029: N N Y N N N Y N N N Y N N N Y N N N Y N
    2030 - 2049: N N Y N N N Y N N N Y N N N Y N N N Y N
    2050 - 2069: N N Y N N N Y N N N Y N N N Y N N N Y N
    2070 - 2089: N N Y N N N Y N N N Y N N N Y N N N Y N
    2090 - 2106: N N Y N N N Y N N N N N N N Y N N
                                     ^ year 2100
    
  3. Nombre de jours jusqu'au premier jour de chaque mois de l'année en cours.

                       Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
    Year with 365 days:  0  31  59  90 120 151 181 212 243 273 304 334
    Year with 366 days:  0  31  60  91 121 152 182 213 244 274 305 335
    

Convertir une date en nombre de secondes depuis le 01/01/1970 est assez simple en utilisant ces tableaux.

Attention, s'il vous plaît!

Le format des chaînes de date et d'heure dépend de la région Windows et des paramètres de langue.Les délimiteurs et l'ordre des jetons attribués aux variables d'environnement Day, Month et Year en premier POUR boucle de GetSeconds doit être adapté au format date/heure local si nécessaire.

Il est nécessaire d'adapter la chaîne de date de la variable d'environnement si format de date dans la variable d'environnement DATE est différent du format de date utilisé par la commande POUR sur %%~tF.

Par exemple quand %DATE% s'étend à Sun 02/08/2015 alors que %%~tF s'étend à 02/08/2015 07:38 PM le code ci-dessous peut être utilisé en modifiant la ligne 4 pour :

call :GetSeconds "%DATE:~4% %TIME%"

Cela entraîne le passage au sous-programme uniquement 02/08/2015 - la chaîne de date sans les 3 lettres de l'abréviation du jour de la semaine et le caractère espace de séparation.

Alternativement, ce qui suit pourrait être utilisé pour transmettre la date actuelle dans le format correct :

call :GetSeconds "%DATE:~-10% %TIME%"

Maintenant, les 10 derniers caractères de la chaîne de date sont transmis à la fonction GetSeconds et donc peu importe si la chaîne de date de la variable d'environnement DATE est avec ou sans jour de la semaine à condition que le jour et le mois comportent toujours 2 chiffres dans l'ordre attendu, c'est-à-direau format dd/mm/yyyy ou dd.mm.yyyy.

Voici le code de lot avec des commentaires explicatifs qui indique simplement quel fichier supprimer et quel fichier conserver C:\Temp arborescence des dossiers, voir le code du premier POUR boucle.

@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem Get seconds since 1970-01-01 for current date and time.
call :GetSeconds "%DATE% %TIME%"
rem Subtract seconds for 7 days from seconds value.
set /A "LastWeek=Seconds-7*86400"

rem For each file in each subdirectory of C:\Temp get last modification date
rem (without seconds -> append second 0) and determine the number of seconds
rem since 1970-01-01 for this date/time. The file can be deleted if seconds
rem value is lower than the value calculated above.

for /F "delims=" %%F in ('dir /A-D-H-S /B /S "C:\Temp"') do (
    call :GetSeconds "%%~tF:0"
    rem if !Seconds! LSS %LastWeek% del /F "%%~fF"
    if !Seconds! LEQ %LastWeek% (
        echo Delete "%%~fF"
    ) else (
        echo Keep   "%%~fF"
    )
)
endlocal
goto :EOF


rem No validation is made for best performance. So make sure that date
rem and hour in string is in a format supported by the code below like
rem MM/DD/YYYY hh:mm:ss or M/D/YYYY h:m:s for English US date/time.

:GetSeconds

rem If there is " AM" or " PM" in time string because of using 12 hour
rem time format, remove those 2 strings and in case of " PM" remember
rem that 12 hours must be added to the hour depending on hour value.

set "DateTime=%~1"
set "Add12Hours=0"
if "%DateTime: AM=%" NEQ "%DateTime%" (
    set "DateTime=%DateTime: AM=%"
) else if "%DateTime: PM=%" NEQ "%DateTime%" (
    set "DateTime=%DateTime: PM=%"
    set "Add12Hours=1"
)

rem Get year, month, day, hour, minute and second from first parameter.

for /F "tokens=1-6 delims=,-./: " %%A in ("%DateTime%") do (
    rem For English US date MM/DD/YYYY or M/D/YYYY
    set "Day=%%B" & set "Month=%%A" & set "Year=%%C"
    rem For German date DD.MM.YYYY or English UK date DD/MM/YYYY
    rem set "Day=%%A" & set "Month=%%B" & set "Year=%%C"
    set "Hour=%%D" & set "Minute=%%E" & set "Second=%%F"
)
rem echo Date/time is: %Year%-%Month%-%Day% %Hour%:%Minute%:%Second%

rem Remove leading zeros from the date/time values or calculation could be wrong.
if "%Month:~0,1%"  EQU "0" ( if "%Month:~1%"  NEQ "" set "Month=%Month:~1%"   )
if "%Day:~0,1%"    EQU "0" ( if "%Day:~1%"    NEQ "" set "Day=%Day:~1%"       )
if "%Hour:~0,1%"   EQU "0" ( if "%Hour:~1%"   NEQ "" set "Hour=%Hour:~1%"     )
if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" )
if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" set "Second=%Second:~1%" )

rem Add 12 hours for time range 01:00:00 PM to 11:59:59 PM,
rem but keep the hour as is for 12:00:00 PM to 12:59:59 PM.
if "%Add12Hours%" == "1" (
    if %Hour% LSS 12 set /A Hour+=12
)
set "DateTime="
set "Add12Hours="

rem Must use 2 arrays as more than 31 tokens are not supported
rem by command line interpreter cmd.exe respectively command FOR.
set /A "Index1=Year-1979"
set /A "Index2=Index1-30"

if %Index1% LEQ 30 (
    rem Get number of days to year for the years 1980 to 2009.
    for /F "tokens=%Index1% delims= " %%Y in ("3652 4018 4383 4748 5113 5479 5844 6209 6574 6940 7305 7670 8035 8401 8766 9131 9496 9862 10227 10592 10957 11323 11688 12053 12418 12784 13149 13514 13879 14245") do set "Days=%%Y"
    for /F "tokens=%Index1% delims= " %%L in ("Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N") do set "LeapYear=%%L"
) else (
    rem Get number of days to year for the years 2010 to 2038.
    for /F "tokens=%Index2% delims= " %%Y in ("14610 14975 15340 15706 16071 16436 16801 17167 17532 17897 18262 18628 18993 19358 19723 20089 20454 20819 21184 21550 21915 22280 22645 23011 23376 23741 24106 24472 24837") do set "Days=%%Y"
    for /F "tokens=%Index2% delims= " %%L in ("N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N N Y N N") do set "LeapYear=%%L"
)

rem Add the days to month in year.
if "%LeapYear%" == "N" (
    for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M"
) else (
    for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M"
)

rem Add the complete days in month of year.
set /A "Days+=Day-1"

rem Calculate the seconds which is easy now.
set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second"

rem Exit this subroutine
goto :EOF

Pour des performances optimales, il serait préférable de supprimer tous les commentaires, c'est-à-diretoutes les lignes commençant par Rem après 0-4 espaces de début.

Et les tableaux peuvent également être rendus plus petits, c'est-à-dirediminuer la plage horaire du 01/01/1980 00:00:00 au 19/01/2038 03:14:07 comme actuellement pris en charge par le code de lot ci-dessus, par exemple au 01/01/2015 au 31/12/2019 comme le code ci-dessous utilise qui supprime réellement les fichiers datant de plus de 7 jours dans C:\Temp arborescence des dossiers.

De plus, le code de lot ci-dessous est optimisé pour le format horaire de 24 heures.

@echo off
setlocal EnableDelayedExpansion
call :GetSeconds "%DATE:~-10% %TIME%"
set /A "LastWeek=Seconds-7*86400"

for /F "delims=" %%F in ('dir /A-D-H-S /B /S "C:\Temp"') do (
    call :GetSeconds "%%~tF:0"
    if !Seconds! LSS %LastWeek% del /F "%%~fF"
)
endlocal
goto :EOF

:GetSeconds
for /F "tokens=1-6 delims=,-./: " %%A in ("%~1") do (
    set "Day=%%B" & set "Month=%%A" & set "Year=%%C"
    set "Hour=%%D" & set "Minute=%%E" & set "Second=%%F"
)
if "%Month:~0,1%"  EQU "0" ( if "%Month:~1%"  NEQ "" set "Month=%Month:~1%"   )
if "%Day:~0,1%"    EQU "0" ( if "%Day:~1%"    NEQ "" set "Day=%Day:~1%"       )
if "%Hour:~0,1%"   EQU "0" ( if "%Hour:~1%"   NEQ "" set "Hour=%Hour:~1%"     )
if "%Minute:~0,1%" EQU "0" ( if "%Minute:~1%" NEQ "" set "Minute=%Minute:~1%" )
if "%Second:~0,1%" EQU "0" ( if "%Second:~1%" NEQ "" set "Second=%Second:~1%" )
set /A "Index=Year-2014"
for /F "tokens=%Index% delims= " %%Y in ("16436 16801 17167 17532 17897") do set "Days=%%Y"
for /F "tokens=%Index% delims= " %%L in ("N Y N N N") do set "LeapYear=%%L"
if "%LeapYear%" == "N" (
    for /F "tokens=%Month% delims= " %%M in ("0 31 59 90 120 151 181 212 243 273 304 334") do set /A "Days+=%%M"
) else (
    for /F "tokens=%Month% delims= " %%M in ("0 31 60 91 121 152 182 213 244 274 305 335") do set /A "Days+=%%M"
)
set /A "Days+=Day-1"
set /A "Seconds=Days*86400+Hour*3600+Minute*60+Second"
goto :EOF

Pour encore plus d'informations sur les formats de date et d'heure et les comparaisons de temps de fichier sous Windows, consultez ma réponse sur Découvrez si le fichier date de plus de 4 heures dans le fichier batch avec de nombreuses informations supplémentaires sur les temps de fichiers.

Puis-je ajouter une humble contribution à ce fil déjà précieux.Je constate que d'autres solutions pourraient supprimer le texte d'erreur réel mais ignorent le %ERRORLEVEL% qui signale un échec dans mon application.ET je veux légitimement %ERRORLEVEL% tant qu'il ne s'agit pas de l'erreur "Aucun fichier trouvé".

Quelques exemples:

Débogage et élimination de l'erreur spécifiquement :

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||echo found success

Utilisation d'un oneliner pour renvoyer le succès ou l'échec de ERRORLEVEL :

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT /B 1||EXIT /B 0

Utiliser un oneliner pour maintenir le ERRORLEVEL à zéro pour réussir dans le contexte d'un fichier batch au milieu d'un autre code (ver > nul réinitialise le ERRORLEVEL) :

forfiles /p "[file path...]\IDOC_ARCHIVE" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&ECHO found error||ver > nul

Pour une étape de travail CmdExec de l'agent SQL Server, j'ai atterri sur ce qui suit.Je ne sais pas si c'est un bug, mais le CmdExec de l'étape ne reconnaît que la première ligne de code :

cmd /e:on /c "forfiles /p "C:\SQLADMIN\MAINTREPORTS\SQL2" /s /m *.txt /d -1 /c "cmd /c del @path" 2>&1 |  findstr /V /O /C:"ERROR: No files found with the specified search criteria."2>&1 | findstr ERROR&&EXIT 1||EXIT 0"&exit %errorlevel%

Si vous disposez du kit de ressources XP, vous pouvez utiliser robocopy pour déplacer tous les anciens répertoires dans un seul répertoire, puis utiliser rmdir pour supprimer uniquement celui-là :

mkdir c:\temp\OldDirectoriesGoHere
robocopy c:\logs\SoManyDirectoriesToDelete\ c:\temp\OldDirectoriesGoHere\ /move /minage:7
rmdir /s /q c:\temp\OldDirectoriesGoHere

Je pense e.La réponse de James est bon car il fonctionne avec des versions non modifiées de Windows dès Windows 2000 SP4 (et peut-être avant), mais il nécessitait d'écrire dans un fichier externe.Voici une version modifiée qui ne crée pas de fichier texte externe tout en conservant la compatibilité :

REM del_old.cmd
REM usage: del_old MM-DD-YYYY
setlocal enabledelayedexpansion
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)

Pour être fidèle à la question d'origine, la voici dans un script qui fait TOUS les calculs pour vous si vous l'appelez avec le nombre de jours comme paramètre :

REM del_old_compute.cmd
REM usage: del_old_compute N
setlocal enabledelayedexpansion
set /a days=%1&set cur_y=%DATE:~10,4%&set cur_m=%DATE:~4,2%&set cur_d=%DATE:~7,2%
for /f "tokens=1 delims==" %%a in ('set cur_') do if "!%%a:~0,1!"=="0" set /a %%a=!%%a:~1,1!+0
set mo_2=28&set /a leapyear=cur_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
set mo_1=31&set mo_3=31&set mo_4=30&set mo_5=31
set mo_6=30&set mo_7=31&set mo_8=31&set mo_9=30
set mo_10=31&set mo_11=30&set mo_12=31
set /a past_y=(days/365)
set /a monthdays=days-((past_y*365)+((past_y/4)*1))&&set /a past_y=cur_y-past_y&set months=0
:setmonth
set /a minusmonth=(cur_m-1)-months
if %minusmonth% leq 0 set /a minusmonth+=12
set /a checkdays=(mo_%minusmonth%)
if %monthdays% geq %checkdays% set /a months+=1&set /a monthdays-=checkdays&goto :setmonth
set /a past_m=cur_m-months
set /a lastmonth=cur_m-1
if %lastmonth% leq 0 set /a lastmonth+=12
set /a lastmonth=mo_%lastmonth%
set /a past_d=cur_d-monthdays&set adddays=::
if %past_d% leq 0 (set /a past_m-=1&set adddays=)
if %past_m% leq 0 (set /a past_m+=12&set /a past_y-=1)
set mo_2=28&set /a leapyear=past_y*10/4
if %leapyear:~-1% equ 0 set mo_2=29
%adddays%set /a past_d+=mo_%past_m%
set d=%past_m%-%past_d%-%past_y%
for /f "tokens=*" %%a IN ('xcopy *.* /d:%d% /L /I null') do @if exist "%%~nxa" set "excludefiles=!excludefiles!;;%%~nxa;;"
for /f "tokens=*" %%a IN ('dir /b') do @(@echo "%excludefiles%"|FINDSTR /C:";;%%a;;">nul || if exist "%%~nxa" DEL /F /Q "%%a">nul 2>&1)

NOTE:Le code ci-dessus prend en compte les années bissextiles, ainsi que le nombre exact de jours de chaque mois.Le seul maximum est le nombre total de jours écoulés depuis le 0/0/0 (après quoi, il renvoie des années négatives).

NOTE:Les calculs ne vont que dans un sens ;il ne peut pas obtenir correctement les dates futures à partir d'une entrée négative (il essaiera, mais dépassera probablement le dernier jour du mois).

Vous pourrez peut-être y parvenir.Vous pouvez jeter un oeil à cette question, pour un exemple plus simple.La complexité vient quand on commence à comparer les dates.Il peut être facile de savoir si la date est supérieure ou non, mais il existe de nombreuses situations à considérer si vous devez réellement obtenir la différence entre deux dates.

En d’autres termes, n’essayez pas d’inventer cela, à moins que vous ne puissiez vraiment pas utiliser les outils tiers.

ce n'est rien d'étonnant, mais je devais faire quelque chose comme ça aujourd'hui et l'exécuter comme tâche planifiée, etc.

fichier batch, DelFilesOlderThanNDays.bat ci-dessous avec un exemple d'exécution avec paramètres :

DelFilesOlderThanNDays.bat 7 C:\dir1\dir2\dir3\logs *.enregistrer

echo off
cls
Echo(
SET keepDD=%1
SET logPath=%2 :: example C:\dir1\dir2\dir3\logs
SET logFileExt=%3
SET check=0
IF [%3] EQU [] SET logFileExt=*.log & echo: file extention not specified (default set to "*.log")
IF [%2] EQU [] echo: file directory no specified (a required parameter), exiting! & EXIT /B 
IF [%1] EQU [] echo: number of days not specified? :)
echo(
echo: in path [ %logPath% ]
echo: finding all files like [ %logFileExt% ]
echo: older than [ %keepDD% ] days
echo(
::
::
:: LOG
echo:  >> c:\trimLogFiles\logBat\log.txt
echo: executed on %DATE% %TIME% >> c:\trimLogFiles\logBat\log.txt
echo: ---------------------------------------------------------- >> c:\trimLogFiles\logBat\log.txt
echo: in path [ %logPath% ] >> c:\trimLogFiles\logBat\log.txt
echo: finding all files like [ %logFileExt% ] >> c:\trimLogFiles\logBat\log.txt
echo: older than [ %keepDD% ] days >> c:\trimLogFiles\logBat\log.txt
echo: ---------------------------------------------------------- >> c:\trimLogFiles\logBat\log.txt
::
FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c echo @path" >> c:\trimLogFiles\logBat\log.txt 2<&1
IF %ERRORLEVEL% EQU 0 (
 FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c echo @path"
)
::
::
:: LOG
IF %ERRORLEVEL% EQU 0 (
 echo:  >> c:\trimLogFiles\logBat\log.txt
 echo: deleting files ... >> c:\trimLogFiles\logBat\log.txt
 echo:  >> c:\trimLogFiles\logBat\log.txt
 SET check=1
)
::
::
IF %check% EQU 1 (
 FORFILES /p %logPath% /s /m %logFileExt% /d -%keepDD% /c "cmd /c del @path"
)
::
:: RETURN & LOG
::
IF %ERRORLEVEL% EQU 0 echo: deletion successfull! & echo: deletion successfull! >> c:\trimLogFiles\logBat\log.txt
echo: ---------------------------------------------------------- >> c:\trimLogFiles\logBat\log.txt

En développant la réponse d'aku, je vois beaucoup de gens poser des questions sur les chemins UNC.Le simple mappage du chemin unc vers une lettre de lecteur rendra les fichiers heureux.Le mappage et le démappage des lecteurs peuvent être effectués par programme dans un fichier batch, par exemple.

net use Z: /delete
net use Z: \\unc\path\to\my\folder
forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"

Cela supprimera tous les fichiers avec une extension .gz datant de plus de 7 jours.Si vous voulez vous assurer que Z :n'est mappé à rien d'autre avant de l'utiliser, vous pouvez faire quelque chose de simple comme

net use Z: \\unc\path\to\my\folder
if %errorlevel% equ 0 (
    forfiles /p Z: /s /m *.gz /D -7 /C "cmd /c del @path"
) else (
    echo "Z: is already in use, please use another drive letter!"
)

Mon Dieu, beaucoup de réponses déjà.Un moyen simple et pratique que j'ai trouvé consistait à exécuter ROBOCOPY.EXE deux fois dans un ordre séquentiel à partir d'une seule instruction de ligne de commande Windows en utilisant le & paramètre.

ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 & ROBOCOPY.EXE SOURCE-DIR TARGET-DIR *.* /MOV /MINAGE:30 /PURGE

Dans cet exemple, cela fonctionne en sélectionnant tous les fichiers (.) datant de plus de 30 jours et en les déplaçant vers le dossier cible.La deuxième commande fait à nouveau la même chose avec l'ajout du PURGE commande qui signifie supprimer les fichiers du dossier cible qui n’existent pas dans le dossier source.Donc essentiellement, la première commande déplace les fichiers et la seconde les supprime car ils n'existent plus dans le dossier source lorsque la deuxième commande est invoquée.

Consultez la documentation de ROBOCOPY et utilisez le commutateur /L lors des tests.

ROBOCOPIE fonctionne très bien pour moi.A l'origine suggéré mon Iman.Mais au lieu de déplacer les fichiers/dossiers vers un répertoire temporaire puis de supprimer le contenu du dossier temporaire, déplacez les fichiers à la corbeille !!!

Voici quelques lignes de mon fichier batch de sauvegarde par exemple :

SET FilesToClean1=C:\Users\pauls12\Temp
SET FilesToClean2=C:\Users\pauls12\Desktop\1616 - Champlain\Engineering\CAD\Backups

SET RecycleBin=C:\$Recycle.Bin\S-1-5-21-1480896384-1411656790-2242726676-748474

robocopy "%FilesToClean1%" "%RecycleBin%" /mov /MINLAD:15 /XA:SH /NC /NDL /NJH /NS /NP /NJS
robocopy "%FilesToClean2%" "%RecycleBin%" /mov /MINLAD:30 /XA:SH /NC /NDL /NJH /NS /NP /NJS

Il nettoie tout ce qui date de plus de 15 jours de mon dossier « Temp » et 30 jours pour tout ce qui se trouve dans mon dossier de sauvegarde AutoCAD.J'utilise des variables car la ligne peut devenir assez longue et je peux les réutiliser pour d'autres emplacements.Il vous suffit de trouver le chemin DOS vers votre corbeille associé à votre identifiant.

C'est sur un ordinateur de travail pour moi et ça marche.Je comprends que certains d'entre vous peuvent avoir des droits plus restrictifs mais essayez quand même ;) Recherchez sur Google des explications sur les paramètres de ROBOCOPY.

Acclamations!

Celui-ci l'a fait pour moi.Cela fonctionne avec une date et vous pouvez soustraire le montant souhaité en années pour remonter dans le temps :

@echo off

set m=%date:~-7,2%
set /A m
set dateYear=%date:~-4,4%
set /A dateYear -= 2
set DATE_DIR=%date:~-10,2%.%m%.%dateYear% 

forfiles /p "C:\your\path\here\" /s /m *.* /d -%DATE_DIR% /c "cmd /c del @path /F"

pause

le /F dans le cmd /c del @path /F force la suppression du fichier spécifique dans certains cas, le fichier peut être en lecture seule.

le dateYear est l'année variable et là, vous pouvez modifier la soustraction selon vos propres besoins

Mon script pour supprimer les fichiers datant de plus d'une année spécifique :

@REM _______ GENERATE A CMD TO DELETE FILES OLDER THAN A GIVEN YEAR
@REM _______ (given in _olderthanyear variable)
@REM _______ (you must LOCALIZE the script depending on the dir cmd console output)
@REM _______ (we assume here the following line's format "11/06/2017  15:04            58 389 SpeechToText.zip")

@set _targetdir=c:\temp
@set _olderthanyear=2017

@set _outfile1="%temp%\deleteoldfiles.1.tmp.txt"
@set _outfile2="%temp%\deleteoldfiles.2.tmp.txt"

  @if not exist "%_targetdir%" (call :process_error 1 DIR_NOT_FOUND "%_targetdir%") & (goto :end)

:main
  @dir /a-d-h-s /s /b %_targetdir%\*>%_outfile1%
  @for /F "tokens=*" %%F in ('type %_outfile1%') do @call :process_file_path "%%F" %_outfile2%
  @goto :end

:end
  @rem ___ cleanup and exit
  @if exist %_outfile1% del %_outfile1%
  @if exist %_outfile2% del %_outfile2%
  @goto :eof

:process_file_path %1 %2
  @rem ___ get date info of the %1 file path
  @dir %1 | find "/" | find ":" > %2
  @for /F "tokens=*" %%L in ('type %2') do @call :process_line "%%L" %1
  @goto :eof

:process_line %1 %2
  @rem ___ generate a del command for each file older than %_olderthanyear%
  @set _var=%1
  @rem  LOCALIZE HERE (char-offset,string-length)
  @set _fileyear=%_var:~0,4%
  @set _fileyear=%_var:~7,4%
  @set _filepath=%2
  @if %_fileyear% LSS %_olderthanyear% echo @REM %_fileyear%
  @if %_fileyear% LSS %_olderthanyear% echo @del %_filepath%
  @goto :eof

:process_error %1 %2
  @echo RC=%1 MSG=%2 %3
  @goto :eof
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top