2008-11-27 18 views
11

Duplicar posibles:
Batch file to delete files older than N daysarchivo por lotes para eliminar los archivos anteriores a una fecha especificada

¿Cómo se crea un archivo por lotes para eliminar los archivos anteriores a una fecha determinada?

Esto no parece funcionar;

:: --------DELOLD.BAT---------- 
@echo off 
SET OLDERTHAN=%1 
IF NOT DEFINED OLDERTHAN GOTO SYNTAX 

for /f "tokens=2" %%i in ('date /t') do set thedate=%%i 
type %1 
pause 
set mm=%thedate:~0,2% 
set dd=%thedate:~3,2% 
set yyyy=%thedate:~6,4% 

set /A dd=%dd% - %OLDERTHAN% 
set /A mm=%mm% + 0 

if /I %dd% GTR 0 goto DONE 
set /A mm=%mm% - 1 
if /I %mm% GTR 0 goto ADJUSTDAY 
set /A mm=12 
set /A yyyy=%yyyy% - 1 

:ADJUSTDAY 
if %mm%==1 goto SET31 
if %mm%==2 goto LEAPCHK 
if %mm%==3 goto SET31 
if %mm%==4 goto SET30 
if %mm%==5 goto SET31 
if %mm%==6 goto SET30 
if %mm%==7 goto SET31 
if %mm%==8 goto SET31 
if %mm%==9 goto SET30 
if %mm%==10 goto SET31 
if %mm%==11 goto SET30 
if %mm%==12 goto SET31 

goto ERROR 

:SET31 
set /A dd=31 + %dd% 
goto DONE 

:SET30 
set /A dd=30 + %dd% 
goto DONE 

:LEAPCHK 
set /A tt=%yyyy% %% 4 
if not %tt%==0 goto SET28 
set /A tt=%yyyy% %% 100 
if not %tt%==0 goto SET29 
set /A tt=%yyyy% %% 400 
if %tt%==0 goto SET29 

:SET28 
set /A dd=28 + %dd% 
goto DONE 

:SET29 
set /A dd=29 + %dd% 

:DONE 
if /i %dd% LSS 10 set dd=0%dd% 
if /I %mm% LSS 10 set mm=0%mm% 
for %%i in (*.*) do (
set FileName=%%i 
call :PROCESSFILE %%~ti 
) 

set mm= 
set yyyy= 
set dd= 
set thedate= 
goto EXIT 

:SYNTAX 
ECHO. 
ECHO USAGE: 
ECHO DELOLD X 
ECHO Where X is the number of days previous to Today. 
ECHO. 
ECHO EX: "DELOLD 5" Deletes files older than 5 days. 
GOTO EXIT 

:PROCESSFILE 
set temp=%1 
set fyyyy=20%temp:~6% 
set fmm=%temp:~0,2% 
set fdd=%temp:~3,2% 
if /I %fyyyy% GTR 2069 set fyyyy=19%temp:~6% 


:: *************************************** 
:: * This is where the files are deleted * 
:: * Change the ECHO command to DEL to * 
:: * delete. ECHO is used for test.  * 
:: *************************************** 
if /I %yyyy%/%mm%/%dd% GEQ %fyyyy%/%fmm%/%fdd% (
ECHO %FileName% 
) 

set temp= 
set fyyyy= 
set fmm= 
set fdd= 

:EXIT 

:: ----------END-DELOLD.BAT------------- 
+0

Se ha publicado un nuevo método basado en un archivo .BAT que utiliza comandos internos CMD.EXE solamente: http://stackoverflow.com/questions/9746778/ms-dos-batch-delete-old-files-in -directory/9747065 # 9747065 – Aacini

Respuesta

-1

No sé si se puede hacer eso con los archivos .BAT y qué pocas herramientas de Windows viene con, pero seguro que puede con Js (JScript) o .vbs archivos (VBScript). Estás haciendo esto en Windows, ¿verdad? Si es así, entonces Windows puede procesar archivos .js y .vbs de la misma manera que los archivos .bat de forma predeterminada. Ellos son mucho más poderosos.

Y, si su objetivo es solo Windows Server 2008, PowerShell es aún mejor (se puede descargar para otras versiones de Windows).

+0

Ver http://stackoverflow.com/a/51069/283863 –

+0

Um ... No te di ese voto negativo. Pero creo que es porque esto es más como un * comentario * que una * respuesta *. –

+0

@Derek - Oh, bien entonces. Lo siento. :) –

0

Me pregunto por qué tienes que utilizar el shell de DOS ole ... Python o Windows Powershell serían las decisiones correctas en el 2008 :)

+0

Está usando set/a. De ninguna manera eso funcionaría en DOS. Así que usa cmd, en realidad, que sigue siendo una opción muy sensata (aunque engorrosa), ya que es lo único que funciona en todos los Windows (excepto WSH, pero puede bloquearse con políticas de grupo). – Joey

6

Editar: lo he descubierto.

Para eliminar todos los archivos anteriores a una fecha determinada:

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"

Para eliminar todos los archivos más recientes que una fecha determinada:

REM del_new.bat 
REM usage: del_new MM-DD-YYYY 
for /f "tokens=*" %%a IN ('xcopy *.* /d:%1 /L /I null') do if exist "%%~nxa" del "%%~nxa"
9

utilizo este script:

//////////////////////////////////////////////////////// 
// Deletes file older than a number of days 
// in the current directory 
//////////////////////////////////////////////////////// 
// Usage: wscript DeleteOlderThan.js [#Days] 
// By default, remove files older than 30 days 
//////////////////////////////////////////////////////// 

function removeDays(date, nDays) 
{ 
    var dateRet = date 
    return dateRet.setDate(date.getDate() - nDays); 
} 

function addSlash(strPath) 
{ 
    var c = strPath.substr(-1, 1); 
    if(c !== '\\' && c !== '/') 
    { 
     strPath += '\\'; 
    } 
    return strPath; 
} 

// Read arguments 
var nDays = WScript.Arguments(0) || 30; 

// Create system objects 
var fs = WScript.CreateObject("Scripting.FileSystemObject"); 
var shell = WScript.CreateObject("WScript.Shell"); 

// Retrieve current directory 
var strDirectoryPath = addSlash(shell.CurrentDirectory); 

// Compute date 
var dateNow = new Date(); 
var dateTest = removeDays(dateNow, nDays); 

// Iterate on files 
var folder = fs.GetFolder(strDirectoryPath); 
var files = folder.Files; 

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

    if(file.DateLastModified < dateTest) 
    { 
     file.Delete(true); 
    } 
} 

que invoco todos los días con:

wscript "C:\Program Files\Utils\DeletesOlderThan.js" 30 
1

Mi solución funciona si

  • o bien tienen una utilidad touch en su sistema (que hago)
  • o puede permitirse el lujo de cambiar temporalmente fecha del sistema usando date comando (que probablemente no es el caso, pero quién sabe)

Aquí es la idea:

  1. En el directorio de destino, cree un archivo de señal (con un nombre único) y con la marca de tiempo igual al tiempo de su umbral de eliminación. Se puede hacer con touch (que acepta la marca de tiempo deseada como parámetro), o al recordar la fecha actual con date /T, cambiar la fecha del sistema al deseado con date <param> y restaurar la fecha original.

  2. Utilice for /f %%I in ('dir /od') para recorrer en iteración todos los archivos ordenados por fecha, eliminándolos uno por uno. Después de encontrar (y eliminar) el archivo de señal, deje de eliminar.

+1

Esto parece un enfoque increíblemente arriesgado en comparación con las otras respuestas aquí. – Dan

+0

@Dan Si se está refiriendo a la posibilidad de que algo se meta con el archivo de señal, puede evitarse dividiendo (2) en dos etapas: ** 2.1 ** construya el script ejecutando el ciclo como se indica arriba, haciéndose eco del del comando con nombre de archivo en un archivo temporal; ** 2.2 ** llame a dicho archivo temporal, pero solo si encontró su archivo de señal. De lo contrario, abortar. De todos modos, esta solución es un desafío, por supuesto. – atzz

+1

Estaba pensando si accidentalmente ordenó los archivos incorrectamente, es posible que elimine miles de archivos antes de llegar al archivo de señal que no quería eliminar. No me gusta la idea de tener un archivo de señal o chequear explícitamente la marca de tiempo de cada archivo antes de que se elimine para estar 100% seguro de que está bien con perderlo. Tampoco entiendo muy bien cómo su enfoque trata con los subdirectorios (no estoy seguro de si ese era un requisito para OP, pero es para mí). – Dan

6

eJames: ¡Encontré tu solución de xcopy funcionando muy bien, de hecho! Lo que más me gusta de él es que debería funcionar en versiones de Windows además del inglés, ya que el formato de los parámetros de XCOPY parece ser independiente de la fecha. ¡Maravilloso! ;]

Una mejora sería pre-crear el archivo FILES_TO_KEEP.TXT de modo que si ningún archivo coincide con el criterio de mantener, la segunda instrucción XCOPY todavía puede continuar y hacer la eliminación (falla si no puede encontrar los FILES_TO_KEEP Archivo .TXT). Aquí está mi script (tenga en cuenta que en este ejemplo lo cambié solo para borrar archivos * .pdf y también cambié el nombre del archivo temporal para asegurarme de que no haya conflictos potenciales, así como para limpiar el archivo temporal después):

@echo off 
SET OLDERTHAN=%1 
IF NOT DEFINED OLDERTHAN GOTO SYNTAX 

echo >> ~~~FILES_TO_KEEP.TXT~ 
for /f "tokens=*" %%a IN ('xcopy *.pdf /d:%1 /L /I null') do if exist %%~nxa echo %%~nxa >> ~~~FILES_TO_KEEP.TXT~ 
for /f "tokens=*" %%a IN ('xcopy *.pdf /L /I /EXCLUDE:~~~FILES_TO_KEEP.TXT~ null') do if exist "%%~nxa" del "%%~nxa" 
del ~~~FILES_TO_KEEP.TXT~ 

GOTO END 

:SYNTAX 
ECHO. 
ECHO USAGE: 
ECHO DELOLD mm-dd-yyyy 
ECHO Where mm-dd-yyyy is the date prior to which you want to delete files. 
ECHO. 
ECHO EX: "DELOLD 10-17-2008" Deletes files older than October 17, 2008. 
ECHO. 
ECHO This should work on any language version of Windows, but has only been 
ECHO tested in English-US versions. 
GOTO END 

:END 
8

Si está en un servidor de Windows y/o tiene instalado el Kit de recursos del servidor, forfiles puede ser exactamente lo que está buscando.

Ejemplos: imprimir todos los nombres de archivo, más de 180 días

forfiles /S /D -180 /C "cmd /C Echo @Path" >olderthan180days.txt 

eliminar todos los archivos PDF, mayores de 365 días

forfiles /S /M *.pdf /D -365 /C "cmd /C Del @Path" 
+0

Gran solución, exactamente lo que necesito – LPChip

1

Tal vez usted lo desea: http://blog.jumlin.com/2010/10/move-files-in-folders-and-subfolders-older-than-one-year/

Eso es una secuencia de comandos que moverá archivos de más de un año, incluso admite varios formatos de fecha y subcarpetas. Puede hacer algunos cambios para que se elimine en lugar de moverlos. Es un guión muy completo con comentarios y explicaciones.

+0

El sitio web está a la venta ahora ... – mdhansen

+0

He actualizado la URL. – NiklasJ

Cuestiones relacionadas