Fichier par lots pour supprimer les fichiers de plus de N jours

je cherche un moyen de supprimer tous les fichiers de plus de 7 jours dans un fichier batch. J'ai cherché sur le web, et j'ai trouvé des exemples avec des centaines de lignes de code, et d'autres qui nécessitaient l'installation d'utilitaires en 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 au moins à distance facile pourrait être fait pour les fichiers batch dans Windows. Je suis à la recherche d'un solution qui fonctionne dans un prompt Standard Windows command, sans aucun utilitaire supplémentaire. Pas de PowerShell ou de Cygwin non plus.

610
demandé sur Stephan 2008-09-09 05:05:28

24 réponses

Profiter:

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

voir forfile documentation pour plus de détails.

pour plus de goodies, se référer à un Index A-Z De La Ligne de commande de Windows XP .

si vous n'avez pas forfiles installé sur votre machine, Copiez-le à partir de N'importe quel Windows Server 2003 sur votre machine Windows XP à %WinDir%\system32\ . C'est possible depuis L'EXE est entièrement compatible entre Windows Server 2003 et Windows XP.

les versions ultérieures de Windows et Windows Server l'installent par défaut.

Pour Windows 7:

la syntaxe a un peu changé. Par conséquent, la commande mise à jour est:

forfiles /p "C:\what\ever" /s /m *.* /D -<number of days> /C "cmd /c del @path"
957
répondu aku 2017-06-22 15:27:53

exécuter la commande suivante 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 et les supprime ensuite par opposition à /move qui déplace les dossiers entiers qui sont ensuite supprimés) via robocopy à un autre endroit, puis exécutez une commande delete sur ce chemin et vous êtes tous bons.

Aussi, si vous avez un répertoire avec beaucoup de données, vous pouvez utiliser /mir switch

69
répondu Iman 2015-10-30 03:24:01

Ok était ennuyé un peu et est venu avec ceci, qui contient ma version D'un homme pauvre Linux Epoch remplacement limitée pour l'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 : changer 7 pour le nombre de jours à garder.

set dSource=C:\temp : C'est le répertoire de départ pour vérifier les fichiers.

NOTES

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 effectivement supprimés

février est codé en 28 jours. Les années bissextiles sont un enfer à ajouter, vraiment. si quelqu'un a une idée qui n'ajouterait pas 10 lignes de code, allez-y et postez donc je l'ajoute à mon code.

epoch : Je n'ai pas pris de temps en considération, car le besoin est de supprimer des fichiers plus anciens qu'une certaine date, en prenant des heures/minutes aurait supprimé des fichiers d'un jour qui était destiné à la conservation.

LIMITATION

epoch prend pour acquis votre format de date courte est AAAA-MM-JJ. Il devra être adapté pour d'autres réglages ou l'exécution de l'évaluation (lire sShortTime, la configuration liée à l'utilisateur, configurer l'ordre de champ approprié dans un filtre et utiliser le filtre pour extraire les données correctes de l'argument).

ai-je mentionné que je déteste l'auto-formation de cet éditeur? il supprime les lignes vides et le copier-coller est un enfer.

j'espère que cela aidera.

21
répondu Jay 2017-09-15 17:08:23
forfiles /p "v:" /s /m *.* /d -3 /c "cmd /c del @path"

, Vous devriez faire /d -3 (3 jours plus tôt) Cela fonctionne très bien pour moi. Donc tous les lots compliqués pourraient être dans la poubelle. Aussi forfiles ne supporte pas les chemins UNC, donc faites une connexion réseau à un lecteur spécifique.

17
répondu Arno Jansen 2013-08-01 08:05:20

Avoir un coup d'oeil à mon réponse à un la même question :

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"

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

mise à jour: je remarque que HerbCSO s'est améliorée sur le script ci-dessus. Je recommande d'utiliser sa version à la place.

16
répondu e.James 2017-05-23 12:03:09

mon ordre est

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

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

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

et la seule question que j'ai: comment ajouter plusieurs masques (par exemple " .journal| .bak")?

tout ce qui concerne les fichiers for.exe que je téléchargé ici (on win XP)

mais si vous utilisez Windows server forfiles.exe devrait être déjà là et il est différent de la version ftp. C'est pourquoi je dois 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"
11
répondu segero 2013-08-01 08:06:34

Pour Windows Server 2008 R2:

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

supprimer .sql dossiers plus vieux que 90 jours.

7
répondu NotJustClarkKent 2012-04-27 22:41:04

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

USAGE ONLY IN COMMAND PROMPT: cscript DelOldFiles.vbs 15

15 signifie supprimer des fichiers de plus de 15 jours dans le passé.

  '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
6
répondu Paris 2011-01-26 01:36:21

utiliser forfiles.

il existe différentes versions. Les premiers utilisent des paramètres de style unix.

Ma version (pour server 2000 - note pas d'espace après les interrupteurs)-

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

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

et l'ajouter à C:\WINDOWS\system32

6
répondu Aidan Ewen 2011-11-14 15:14:50

IMO, JavaScript devient progressivement une norme universelle de script: il est probablement disponible dans plus de produits que tout autre langage de script (dans Windows, il est disponible en utilisant L'hôte Windows Scripting). Je dois nettoyer de vieux fichiers dans beaucoup de dossiers, donc voici une fonction JavaScript pour le 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, il suffit d'ajouter un autre appel à la fonction clearFolder (). Ce code particulier préserve également les fichiers exe et dll, et nettoie les sous-dossiers.

5
répondu Graham Laight 2013-04-26 10:57:48

Que pensez-vous de cette modification sur 7daysclean.cmd pour tenir compte d'une année bissextile?

Il peut être fait en moins de 10 lignes de code!

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

Modifier par Mofi:

la condition ci-dessus contribuée par J. R. évalue toujours à false en raison de la syntaxe invalide.

et Month GEQ 2 est également erroné parce que l'ajout de 86400 secondes pour un jour de plus doit être fait dans une année bissextile seulement pour les mois de Mars à décembre, mais pas pour février.

un code de travail pour tenir compte du leap day - dans l'année courante seulement - dans le fichier de lots 7daysclean.cmd posté par Jay 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
5
répondu J.R. 2017-05-23 12:03:09

Pour windows 2012 R2 le suivant fonctionnerait:

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

pour voir les fichiers qui seront supprimés utilisez cette

    forfiles /p "c:\FOLDERpath" /d -30 /c "cmd /c echo @path @fdate"
5
répondu Viktor Ka 2015-07-25 15:37:04

il y a très souvent des questions relatives date/heure à résoudre avec le fichier batch. Mais interprète en ligne de commande cmd.exe n'a pas de fonction pour les calculs date/heure. Beaucoup de bonnes solutions de travail utilisant des applications ou des scripts de console supplémentaires ont déjà été publiées ici, sur d'autres pages de débordement de pile et sur d'autres sites web.

courant pour les opérations basées sur la date/heure est l'exigence de convertir une chaîne date/heure en secondes depuis un jour déterminé. Très commun est 1970-01-01 00:00: 00 UTC. Mais n'importe quel jour plus tard pourrait aussi être utilisé en fonction de la plage de date nécessaire pour soutenir une tâche spécifique.

Jay posted 7daysclean.cmd contenant une solution rapide de" date à la seconde "pour l'interprète en ligne de commande cmd.exe . Mais il ne prend pas les années bissextiles corrects en compte. J. R. posté un add-on pour la prise de saut de jour dans l'année en cours en compte, mais en ignorant les autres années bissextiles depuis l'année de base, c'est à dire depuis 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 de 1970-01-01 dans les fonctions de conversion date/heure dans Mes applications écrites en C/C++.

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

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

D'abord, les tableaux:

  1. jours depuis 1970-01-01 00:00: 00 UTC pour chaque année incluant 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
    

    calculer les secondes pour les années 2039 à 2106 avec l'époque commençant 1970-01-01 est seulement possible avec l'utilisation d'une variable non signée de 32 bits, c.-à-d. non signée longue (ou int) dans 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 (0x7fffff) qui est 2038-01-19 03: 14: 07.

  2. renseignements sur l'année bissextile (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
    

il est assez facile de convertir une date en nombre de secondes depuis 1970-01-01 en utilisant ces tableaux.

Attention s'il vous plaît!

le format des chaînes date et heure dépend de la région de 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 dans le premier pour boucle de GetSeconds doivent être adaptés au format date/heure locale si nécessaire.

Il est nécessaire d'adapter la chaîne de date de la variable d'environnement si le 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 lorsque %DATE% devient Sun 02/08/2015 alors que %%~tF devient 02/08/2015 07:38 PM le code ci-dessous peut être utilisé en modifiant la ligne 4 en:

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

cette conséquence en passant à sous-programme juste 02/08/2015 - la chaîne de date sans les 3 lettres de l'abréviation de jour de semaine et la séparation caractère d'espace.

on peut aussi utiliser la formule suivante pour passer 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 passés à la fonction GetSeconds et par conséquent il n'importe pas si la chaîne de date de la variable d'environnement DATE est avec ou sans jour de semaine aussi longtemps que le jour et le mois sont toujours avec 2 chiffres dans l'ordre prévu, c.-à-d. dans le format dd/mm/yyyy ou dd.mm.yyyy .

voici le code de lot avec des commentaires explicatifs qui ne sortent que le fichier à supprimer et le fichier à conserver dans C:\Temp l'arborescence des dossiers, voir le code de la première boucle pour .

@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 une performance optimale, il serait préférable de supprimer tous les commentaires, c'est-à-dire toutes les lignes commençant par rem après 0-4 espaces.

et les tableaux peuvent être faits aussi plus petits, c'est-à-dire diminuer la plage de temps de 1980-01-01 00:00:00 à 2038-01-19 03:14:07 Comme actuellement supporté par le code de lot ci-dessus par exemple à 2015-01-01 à 2019-12-31 comme le code ci-dessous utilise qui supprime vraiment les fichiers de plus de 7 jours dans C:\Temp arbre de chemise.

en outre, le code de lot ci-dessous est optimisé pour un format 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 d'Heure de fichier sur Windows voir ma réponse sur savoir si le fichier est âgé de plus de 4 heures dans un fichier de commandes avec beaucoup d'informations supplémentaires sur le fichier fois.

5
répondu Mofi 2017-05-23 12:10:54

puis-je ajouter une humble contribution à ce fil déjà précieux. Je trouve que d'autres solutions pourraient se débarrasser du texte d'erreur réel, mais ignorent le %ERRORLEVEL% qui signale un échec dans mon application. Et je veux légitimement %ERRORLEVEL % tant que ce n'est pas l'erreur "No files found".

Quelques Exemples:

déboguer et éliminer 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

""
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 garder le niveau D'erreur à zéro pour le succès dans le contexte d'un fichier de lots au milieu d'un autre code (ver > nul réinitialise le niveau d'erreur):

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 un Agent de Serveur SQL CmdExec étape de travail j'ai atterri sur ce qui suit. Je ne sais pas si c'est un bug, mais le CmdExec dans le pas 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%
4
répondu Sting 2015-04-08 13:13:35

si vous avez le 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 juste celui-ci:

mkdir c:\temp\OldDirectoriesGoHere
robocopy c:\logs\SoManyDirectoriesToDelete\ c:\temp\OldDirectoriesGoHere\ /move /minage:7
rmdir /s /q c:\temp\OldDirectoriesGoHere
3
répondu neuracnu 2010-12-08 00:56:02

I think E. La réponse de James est bonne car elle fonctionne avec des versions non modifiées de Windows aussi tôt que Windows 2000 SP4 (et peut-être plus tôt), mais il a fallu écrire à un fichier externe. Voici une version modifiée qui ne crée pas de fichier texte externe tout en maintenant 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 originale, voici dans un script qui fait tout le calcul 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 tient compte des années bissextiles, ainsi que du nombre exact de jours dans chaque mois. Le seul maximum est le nombre total de jours qu'il y a eu depuis 0/0/0 (après cela il retourne années négatives).

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

3
répondu Lectrode 2017-05-23 12:34:59

vous pourriez être capable d'enlever ça. Vous pouvez jeter un oeil à cette question , pour un exemple plus simple. La complexité vient, quand vous commencez à comparer les dates. Il peut être facile de dire si la date est plus grande ou pas, mais il ya 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 ceci, à moins que vous ne puissiez vraiment pas utiliser les outils tiers.

2
répondu Paulius 2017-05-23 12:34:59

ce n'est rien d'étonnant, mais j'avais besoin de faire quelque chose comme cela aujourd'hui et le faire fonctionner comme tâche prévue, etc.

fichier batch, DelFilesOlderThanNDays.chauve-souris au-dessous de l'échantillon exec w/ params:

DelFilesOlderThanNDays.chauve-souris 7 C:\dir1\dir2\dir3\logs *.log

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
2
répondu Goran B. 2013-12-19 00:01:20

S'étendant sur la réponse d'aku, je vois beaucoup de gens qui posent des questions sur UNC paths. Il suffit de mapper le chemin unc à une lettre de lecteur pour rendre forfiles heureux. Le mappage et le démontage des disques peuvent être faits programmatiquement dans un dossier de fournée, 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 un .GZ extension qui sont plus de 7 jours. Si vous voulez vous assurer que Z: n'est pas mappé à quoi que ce soit 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!"
)
2
répondu Tobias Järvelöv 2014-03-14 10:14:47

ROBOCOPY fonctionne très bien pour moi. Initialement suggéré mon Iman. Mais au lieu de déplacer les fichiers/dossiers dans un répertoire temporaire puis de supprimer le contenu du dossier temporaire, déplacer les fichiers vers la corbeille!!!

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

SET FilesToClean1=C:\Users\pauls12\Temp
SET FilesToClean2=C:\Users\pauls12\Desktop16 - 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 rien de plus que 15 jours de mon dossier "temporaire" et de 30 jours pour rien, à mon Dossier de sauvegarde AutoCAD. J'utilise des variables parce que la ligne peut être assez longue et je peux les réutiliser pour d'autres emplacements. Vous avez juste besoin de trouver le chemin dos de votre corbeille associé à votre identifiant.

C'est sur un ordinateur de travail pour moi et ça fonctionne. Je comprends que certains d'entre vous peuvent avoir plus restrictives de droits, mais tente quand même;) de Recherche Google pour obtenir des explications sur la ROBOCOPY paramètres.

santé!

1
répondu Shawn Pauliszyn 2016-08-15 15:29:17

Gosh, beaucoup de réponses déjà. J'ai trouvé un moyen simple et pratique d'exécuter ROBOCOP.EXE deux fois dans l'ordre séquentiel à partir d'une instruction en ligne de commande Windows utilisant le paramètre et .

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

dans cet exemple, il fonctionne en sélectionnant tous les fichiers ( . ) qui ont plus de 30 jours et les déplacent vers le dossier cible. La seconde commande fait la même chose avec l'ajout du PURGE commande qui signifie supprimer les fichiers dans le dossier cible qui n'existent pas dans le dossier source. Ainsi, essentiellement, la première commande déplace les fichiers et la seconde supprime parce qu'ils n'existent plus dans le dossier source lorsque la seconde commande est invoquée.

consultez la documentation de ROBOCOPY et utilisez l'interrupteur /L lors des tests.

1
répondu GBGOLC 2018-03-16 13:33:56

vous n'allez probablement pas trouver une solution totalement non installable sauf un fichier bat compliqué ou un script windows. J'utilise delen , je le dépose dans un répertoire système puis je l'utilise comme la commande del dans n'importe quel fichier bat.

0
répondu bryan314 2008-09-09 01:42:09

celui-ci l'a fait pour moi. Il fonctionne avec une date et vous pouvez soustraire le montant voulu 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 forces spécifiques fichier à supprimer dans certains cas, le fichier peut être en lecture seule.

la Variable dateYear est la Variable de l'année et vous pouvez modifier le substrat en fonction de vos propres besoins

0
répondu Snickbrack 2017-05-19 08:49:54

mon script pour supprimer des fichiers plus anciens qu'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
0
répondu efdummy 2017-07-15 09:26:25