714 votes

Fichier batch 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 fait des recherches sur le Web et j'ai trouvé des exemples comportant des centaines de lignes de code, et d'autres qui nécessitaient l'installation d'utilitaires de ligne de commande supplémentaires pour accomplir cette tâche.

Des choses similaires peuvent être fait en BASH en seulement quelques lignes de code. Il semble que l'on pourrait faire quelque chose d'au moins aussi simple pour les fichiers batch sous Windows. Je cherche une solution qui fonctionne dans une invite de commande Windows standard, sans utilitaires supplémentaires. Je vous prie de ne pas utiliser PowerShell ou Cygwin.

8 votes

Jeff Atwood a répondu à cette question sur Serverfault et je pense qu'elle devrait être documentée ici. serverfault.com/questions/49614/suppression de fichiers de moins de x jours

0 votes

Une nouvelle méthode basée sur un fichier .BAT qui utilise uniquement les commandes internes de CMD.EXE a été publiée ici : stackoverflow.com/questions/9746778/

1 votes

gehrcke.de/timegaps a été conçu à cet effet. Il permet même un schéma de suppression plus sophistiqué : en plus de conserver les fichiers des 7 derniers jours, il permet aussi, par exemple, de conserver un fichier pour chacune des 8 dernières semaines, 12, mois, 2 ans.

1135voto

aku Points 54867

Profitez-en :

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

Voir forfiles documentation pour plus de détails.

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

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

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

Pour Windows 7 et les versions plus récentes (y compris Windows 10) :

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"

0 votes

Je n'ai pas de forfiles sur ma machine XP (sp3) - d'où cela vient-il ?

13 votes

Devrait être del @FILE, la casse importe Je suggère également d'utiliser /c echo @FILE pour les tests.

42 votes

@Russell : @PATH est le chemin complet, y compris le nom. @FILE est seulement le nom, donc si vous avez affaire à des sous-dossiers, cela ne fonctionnera pas.

79voto

Iman Points 279

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 et les supprime ensuite, par opposition à /move qui déplace des arbres de fichiers entiers qui sont ensuite supprimés) via robocopy vers un autre emplacement, puis exécutez une commande de suppression sur ce chemin et tout va bien.

De même, si vous avez un répertoire contenant beaucoup de données, vous pouvez utiliser /mir commutateur

5 votes

Dans la plupart des cas, il s'agit d'une réponse assez peu pratique. Si j'ai un répertoire contenant beaucoup de données, cela ne fonctionnera pas bien. J'opterais pour l'une des réponses qui le font "en place".

5 votes

@adamb0mb cela n'est en aucun cas irréalisable - si "destination" se trouve sur le même système de fichiers que "source" l'opération de déplacement est assez légère. Comme robocopy est vraiment robuste, il fonctionnera en fait pour n'importe quelle taille de répertoire, des noms de fichiers obscurs, des longueurs de chemin arbitraires et inclura des répertoires si vous en avez besoin - ce qui ne peut certainement pas être dit de beaucoup d'autres utilitaires Windows. J'utiliserais rd /s /q c:\destination au lieu de la del ou même utiliser une autre commande robocopy /mir c:\emptydir c:\destination pour vider le répertoire si vous prévoyez des problèmes avec les noms de fichiers.

12 votes

De plus, robocopy prend en charge les chemins UNC - qui forfiles de la réponse acceptée ne suffira pas.

26voto

Jay Points 774

Je m'ennuyais un peu et j'ai trouvé ceci, qui contient ma version d'un remplacement d'époque Linux du pauvre, limité à 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 : Changer 7 pour le nombre de jours à conserver.

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

NOTES

C'est un 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

pour que les fichiers soient réellement supprimés

Février L'année bissextile : est codée en dur à 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-la pour que je l'ajoute à mon code.

époque : Je n'ai pas pris en compte le temps, comme le besoin est de supprimer les fichiers plus anciens qu'une certaine date, prendre les heures/minutes aurait supprimé les fichiers d'un jour qui était destiné à être conservé.

LIMITATION

époque prend pour acquis que votre format de date courte est AAAA-MM-JJ. Il faudrait l'adapter pour d'autres paramètres ou une évaluation en cours d'exécution (lire sShortTime, configuration liée à l'utilisateur, configurer l'ordre correct 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 l'auto-formatage de cet éditeur ? Il supprime les lignes vides et le copier-coller est un enfer.

J'espère que cela vous aidera.

5 votes

+1 pour le code non destructif, j'essaierai de garder cela à l'esprit lorsque je fournirai moi-même des exemples de code.

6 votes

En retard et sans aucun rapport avec le sujet, mais 7daysclean.cmd ça semble être un nom génial pour un groupe de Synth-Punk.

23voto

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

Vous devriez faire /d -3 (3 jours plus tôt) Cela fonctionne bien pour moi. Ainsi, tous les lots compliqués peuvent être mis à la poubelle. Aussi forfiles ne prennent pas en charge les chemins UNC, il faut donc établir une connexion réseau vers un lecteur spécifique.

3 votes

Même erreur que dans les autres réponses (y compris celle qui a été acceptée). D'où vient cette étrange habitude de spécifier *.* proviennent-ils ? Wildcard *.* ne correspond pas à tous les fichiers de Windows. Il ne correspond qu'aux fichiers avec . dans leur nom. L'OP n'a jamais dit qu'il fallait . dans le nom du fichier. Le paramètre approprié est /M * mais c'est la valeur par défaut de toute façon. Il n'y a pas besoin de /M du tout.

0 votes

@AnT : Vous êtes sûr ? Je pense *.* se comporte exactement comme * dans Windows. En fait, je viens juste de l'essayer sur mon ordinateur, et dir *.* effectivement listé test file un fichier sans extension.

1 votes

@Andreas Rejbrand : Je trouve cela surprenant aussi, mais le traitement des *.* est incohérente entre, disons, dir et -m option de forfiles . Le site -m *.* mask ignore en effet les noms de fichiers sans extension, comme je l'ai indiqué dans mon commentaire ci-dessus (essayez vous-même). La partie amusante ici est que la documentation MS indique explicitement que -m *.* est la valeur par défaut. Cependant, si vous l'essayez dans la vie réelle, vous verrez que la valeur par défaut est en fait -m * - tous les fichiers sont itérés.

17voto

e.James Points 51680

Jetez un coup d'œil à mon réponse à 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.

mettre à jour : Je remarque que HerbCSO a amélioré le script ci-dessus. Je recommande d'utiliser sa version à la place.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X