Estoy buscando una forma de eliminar todos los archivos de más de 7 días en un archivo por lotes. Busqué en la web y encontré algunos ejemplos con cientos de líneas de código, y otros que requerían instalar utilidades de línea de comandos adicionales para realizar la tarea.
Se pueden hacer cosas similares en BASH en solo un par de líneas de código. Parece que se podría hacer algo al menos remotamente fácil para los archivos por lotes en Windows. Estoy buscando una solución que funcione en un símbolo del sistema estándar de Windows, sin ninguna utilidad adicional. Por favor, tampoco PowerShell o Cygwin.
Respuestas:
Disfrutar:
Ver
forfiles
documentación para más detalles.Para obtener más ventajas, consulte un índice AZ de la línea de comandos de Windows XP .
Si no lo ha
forfiles
instalado en su máquina, cópielo desde cualquier Windows Server 2003 a su máquina con Windows XP en%WinDir%\system32\
. Esto es posible ya que el EXE es totalmente compatible entre Windows Server 2003 y Windows XP.Las versiones posteriores de Windows y Windows Server lo tienen instalado de manera predeterminada.
Para Windows 7 y posterior (incluido Windows 10):
La sintaxis ha cambiado un poco. Por lo tanto, el comando actualizado es:
fuente
Ejecute los siguientes comandos :
Mueva todos los archivos (usando / mov, que mueve los archivos y luego los elimina en lugar de / move que mueve archivos completos que luego se eliminan) a través de robocopy a otra ubicación, y luego ejecute un comando de eliminación en esa ruta y estará todo bueno.
Además, si tiene un directorio con muchos datos, puede usar el
/mir
interruptorfuente
rd /s /q c:\destination
embargo, usaría en lugar deldel
comando o incluso usaría otrarobocopy /mir c:\emptydir c:\destination
ejecución para vaciar el directorio si espera problemas con los nombres de archivo.forfiles
desde la respuesta aceptada, no funcionará.C:\test
más de 7 días. Para eliminar los archivos, cambieecho
adel
:forfiles /p "C:\test" /m "*.*" /c "cmd /c echo @file" /D -7
Ok se aburrió un poco y se me ocurrió esto, que contiene mi versión del reemplazo de época de Linux de un pobre limitado para uso diario (sin retención de tiempo)
7daysclean.cmd
USO
set /a strip=day*7
: Cambie 7 por el número de días para guardar.set dSource=C:\temp
: Este es el directorio de inicio para buscar archivos.NOTAS
Este es un código no destructivo, mostrará lo que habría sucedido.
Cambio :
a algo como:
así que los archivos realmente se eliminan
Febrero : está codificado a 28 días. Bissextile años es un infierno agregar, realmente. si alguien tiene una idea que no agregaría 10 líneas de código, continúe y publique para que lo agregue a mi código.
época : no tomé el tiempo en consideración, ya que la necesidad es eliminar archivos anteriores a una fecha determinada, tomar horas / minutos habría eliminado archivos de un día destinado a su mantenimiento.
LIMITACIÓN
época da por sentado que su formato de fecha corta es AAAA-MM-DD. Tendría que adaptarse para otras configuraciones o una evaluación en tiempo de ejecución (lea sShortTime, configuración vinculada por el usuario, configure el orden de campo adecuado en un filtro y use el filtro para extraer los datos correctos del argumento).
¿Mencioné que odio el auto formateo de este editor? elimina las líneas en blanco y copiar y pegar es un infierno.
Espero que esto ayude.
fuente
7daysclean.cmd
alguna , pero suena como un nombre increíble para una banda de Synth-Punk.Deberías hacerlo
/d -3
(3 días antes) Esto funciona bien para mí. Entonces, todos los lotes complicados podrían estar en la papelera. Tampocoforfiles
admite rutas UNC, por lo tanto, realice una conexión de red a una unidad específica.fuente
*.*
viene este extraño hábito de especificar ? El comodín*.*
no coincide con todos los archivos en Windows. Solo coincide con los archivos.
en sus nombres. El OP nunca dijo nada acerca de requerir.
en el nombre del archivo. El parámetro adecuado es/M *
, pero este es el predeterminado de todos modos. No hay necesidad de/M
nada.*.*
comporta exactamente como*
en Windows. De hecho, acabo de probarlo en mi computadora, y dedir *.*
hecho enumerétest file
un archivo sin extensión.*.*
es inconsistente entre, digamos,dir
y la-m
opción deforfiles
. La-m *.*
máscara de hecho omitirá los nombres de archivo sin extensión, como dije en mi comentario anterior (pruébelo usted mismo). La parte divertida aquí es que la documentación de MS establece explícitamente que-m *.*
es el valor predeterminado. Sin embargo, si lo prueba en la vida real, verá que el valor predeterminado es en realidad-m *
: todos los archivos están iterados.*.*
máscara se aplicó a todos los archivos. Mi pregunta retórica sobre "este extraño hábito" no fue solicitada, ya que tratar*.*
y,*
como equivalente, es una convención de Windows de larga data. Sin embargo, la/m
opciónforfiles
viola esa convención por alguna razón.Echa un vistazo a mi respuesta a una pregunta similar :
Esto elimina archivos anteriores a una fecha determinada. Estoy seguro de que puede modificarse para retroceder siete días después de la fecha actual.
Actualización: Noto que HerbCSO ha mejorado en el script anterior. Recomiendo usar su versión en su lugar.
fuente
Mi comando es
@PATH
- es solo el camino en mi caso, así que tuve que usar@PATH\@FILE
También
forfiles /?
no funciona para mí también, peroforfiles
(sin "?") funcionó bien.Y la única pregunta que tengo: ¿cómo agregar varias máscaras (por ejemplo, " .log | .bak")?
Todo esto con respecto a forfiles.exe que descargué aquí (en win XP)
Pero si está utilizando el servidor de Windows forfiles.exe ya debería estar allí y es diferente de la versión ftp. Es por eso que debería modificar el comando.
Para Windows Server 2003 estoy usando este comando:
fuente
A menudo hay preguntas relacionadas con la fecha / hora relativa para resolver con un archivo por lotes. Pero el intérprete de línea de comandos cmd.exe no tiene función para los cálculos de fecha / hora. Ya se han publicado muchas buenas soluciones de trabajo que utilizan aplicaciones o scripts de consola adicionales, en otras páginas de Stack Overflow y en otros sitios web.
Común para operaciones basadas en fecha / hora es el requisito de convertir una cadena de fecha / hora a segundos desde un día determinado. Muy común es 1970-01-01 00:00:00 UTC. Pero cualquier día posterior también podría usarse dependiendo del rango de fechas requerido para respaldar una tarea específica.
Jay publicó 7daysclean.cmd que contiene una solución rápida de "fecha a segundos" para el intérprete de línea de comandos cmd.exe . Pero no tiene en cuenta los años bisiestos correctos. JR publicó un complemento para tener en cuenta el día bisiesto en el año actual, pero ignorando los otros años bisiestos desde el año base, es decir, desde 1970.
Utilizo desde hace 20 años tablas estáticas (matrices) creadas una vez con una pequeña función C para obtener rápidamente la cantidad de días, incluidos los días bisiestos desde 1970-01-01 en funciones de conversión de fecha / hora en mis aplicaciones escritas en C / C ++.
Este método de tabla muy rápido se puede usar también en código por lotes usando el comando FOR . Así que decidí codificar la subrutina por lotes
GetSeconds
que calcula el número de segundos desde 1970-01-01 00:00:00 UTC para una cadena de fecha / hora pasada a esta rutina.Nota: los segundos bisiestos no se tienen en cuenta ya que los sistemas de archivos de Windows tampoco admiten segundos bisiestos.
Primero, las tablas:
Días desde 1970-01-01 00:00:00 UTC para cada año, incluidos los días bisiestos.
El cálculo de los segundos para el año 2039 a 2106 con una época que comienza en 1970-01-01 solo es posible con el uso de una variable de 32 bits sin signo, es decir, sin signo largo (o sin signo int) en C / C ++.
Pero cmd.exe utiliza para expresiones matemáticas una variable de 32 bits con signo. Por lo tanto, el valor máximo es 2147483647 (0x7FFFFFFF) que es 2038-01-19 03:14:07.
Información del año bisiesto (No / Sí) para los años 1970 a 2106.
Número de días hasta el primer día de cada mes en el año actual.
Convertir una fecha en un número de segundos desde 1970-01-01 es bastante fácil usando esas tablas.
¡Atención por favor!
El formato de las cadenas de fecha y hora depende de la configuración de idioma e región de Windows. Los delimitadores y el orden de los tokens asignados a las variables de entorno
Day
,Month
yYear
en el primer bucle FOR,GetSeconds
deben adaptarse al formato de fecha / hora local si es necesario.Es necesario adaptar la cadena de fecha de la variable de entorno si el formato de fecha en la variable de entorno FECHA es diferente al formato de fecha utilizado por el comando FOR activado
%%~tF
.Por ejemplo, cuando se
%DATE%
expande aSun 02/08/2015
mientras se%%~tF
expande al02/08/2015 07:38 PM
código siguiente, se puede usar modificando la línea 4 para:Esto da como resultado pasar a la subrutina solo
02/08/2015
: la cadena de fecha sin las 3 letras de la abreviatura del día de la semana y el carácter de espacio de separación.Alternativamente, lo siguiente podría usarse para pasar la fecha actual en el formato correcto:
Ahora los últimos 10 caracteres de la cadena de fecha se pasan a la función
GetSeconds
y, por lo tanto, no importa si la cadena de fecha de la variable de entorno DATE está con o sin día de la semana, siempre que el día y el mes siempre tengan 2 dígitos en el orden esperado, es decir, en formatodd/mm/yyyy
odd.mm.yyyy
.Aquí está el código de lote con comentarios explicativos que solo muestran qué archivo eliminar y qué archivo mantener en el
C:\Temp
árbol de carpetas, vea el código del primer bucle FOR .Para un rendimiento óptimo, sería mejor eliminar todos los comentarios, es decir, todas las líneas que comienzan con rem después de 0-4 espacios iniciales .
Y las matrices se pueden hacer también más pequeñas, es decir, disminuyendo el rango de tiempo desde 1980-01-01 00:00:00 hasta 2038-01-19 03:14:07 como lo admite actualmente el código de lote anterior, por ejemplo, a 2015-01 -01 a 2019-12-31 como se usa en el siguiente código, que realmente elimina archivos de más de 7 días en el
C:\Temp
árbol de carpetas.Además, el siguiente código de lote está optimizado para el formato de 24 horas.
Para obtener aún más información sobre formatos de fecha y hora y comparaciones de tiempo de archivo en Windows, vea mi respuesta en Averiguar si el archivo tiene más de 4 horas en un archivo por lotes con mucha información adicional sobre los tiempos de archivo.
fuente
Copie este código y guárdelo como
DelOldFiles.vbs
.USO EN CMD:
cscript //nologo DelOldFiles.vbs 15
15 significa eliminar archivos anteriores a 15 días.
fuente
Para Windows Server 2008 R2:
Esto eliminará todos los archivos .sql anteriores a 90 días.
fuente
Use forfiles.
Hay diferentes versiones Los primeros usan parámetros de estilo unix.
Mi versión (para el servidor 2000 - tenga en cuenta que no hay espacio después de los conmutadores) -
Para agregar forfiles a XP, obtenga el exe de ftp://ftp.microsoft.com/ResKit/y2kfix/x86/
y agregarlo a C: \ WINDOWS \ system32
fuente
*.*
enforfiles
no coincide con todos los archivos. Solo coincide con los archivos.
en sus nombres (es decir, archivos con extensiones). El OP nunca dijo nada acerca de requerir.
en el nombre del archivo. El parámetro adecuado es/M *
, pero este es el predeterminado de todos modos. No hay necesidad de/M
nada.Para Windows 2012 R2 lo siguiente funcionaría:
para ver los archivos que se eliminarán, use esto
fuente
En mi opinión, JavaScript se está convirtiendo gradualmente en un estándar de scripting universal: probablemente esté disponible en más productos que cualquier otro lenguaje de scripting (en Windows, está disponible usando Windows Scripting Host). Tengo que limpiar archivos viejos en muchas carpetas, así que aquí hay una función de JavaScript para hacer eso:
Para borrar cada carpeta, simplemente agregue otra llamada a la función clearFolder (). Este código particular también conserva los archivos exe y dll, y también limpia las subcarpetas.
fuente
¿Qué tal esta modificación en 7daysclean.cmd para tener en cuenta un año bisiesto?
¡Se puede hacer en menos de 10 líneas de codificación!
Editar por Mofi:
La condición anterior aportada por JR se evalúa siempre como falsa debido a una sintaxis no válida.
Y
Month GEQ 2
también está mal porque agregar 86400 segundos por un día más debe hacerse en un año bisiesto solo para los meses de marzo a diciembre, pero no para febrero.Un código de trabajo para tener en cuenta el día bisiesto, solo en el año actual, en el archivo por lotes 7daysclean.cmd publicado por Jay sería:
fuente
¿Puedo agregar una humilde contribución a este hilo ya valioso? Estoy descubriendo que otras soluciones pueden deshacerse del texto de error real pero están ignorando el% ERRORLEVEL% que indica un error en mi aplicación. Y legítimamente quiero% ERRORLEVEL% siempre que no sea el error "No se encontraron archivos".
Algunos ejemplos:
Depuración y eliminación del error específicamente:
Usando un oneliner para devolver ERRORLEVEL exitoso o fallido:
Usando un oneliner para mantener el ERRORLEVEL en cero para el éxito dentro del contexto de un archivo por lotes en medio de otro código (ver> nul restablece el ERRORLEVEL):
Para un paso de trabajo CmdExec del Agente SQL Server, aterricé en lo siguiente. No sé si es un error, pero el CmdExec dentro del paso solo reconoce la primera línea de código:
fuente
Gosh, muchas respuestas ya. Una ruta simple y conveniente que encontré fue ejecutar ROBOCOPY.EXE dos veces en orden secuencial desde una sola instrucción de línea de comando de Windows usando el parámetro & .
En este ejemplo, funciona seleccionando todos los archivos ( . ) Que tienen más de 30 días y moviéndolos a la carpeta de destino. El segundo comando vuelve a hacer lo mismo con la adición del comando PURGE, que significa eliminar archivos en la carpeta de destino que no existen en la carpeta de origen. Esencialmente, el primer comando MUEVE archivos y el segundo ELIMINA porque ya no existen en la carpeta de origen cuando se invoca el segundo comando.
Consulte la documentación de ROBOCOPY y use el modificador / L cuando realice la prueba.
fuente
Si tiene el kit de recursos XP, puede usar robocopy para mover todos los directorios antiguos a un solo directorio, luego use rmdir para eliminar solo ese:
fuente
Creo que la respuesta de e.James es buena, ya que funciona con versiones no modificadas de Windows desde Windows 2000 SP4 (y posiblemente antes), pero requería escribir en un archivo externo. Aquí hay una versión modificada que no crea un archivo de texto externo mientras mantiene la compatibilidad:
Para ser fiel a la pregunta original, aquí está en un script que hace TODAS las matemáticas por usted si lo llama con el número de días como parámetro:
NOTA: El código anterior tiene en cuenta los años bisiestos, así como la cantidad exacta de días en cada mes. El único máximo es el número total de días que ha habido desde 0/0/0 (después de eso devuelve años negativos).
NOTA: Las matemáticas solo van en un sentido; no puede obtener correctamente las fechas futuras de la entrada negativa (lo intentará, pero probablemente pasará el último día del mes).
fuente
Es posible que puedas lograr esto. Puedes echar un vistazo a esta pregunta , para un ejemplo más simple. La complejidad viene cuando comienzas a comparar las fechas. Puede ser fácil saber si la fecha es mayor o no, pero hay muchas situaciones a considerar si necesita obtener la diferencia entre dos fechas.
En otras palabras, no intentes inventar esto, a menos que realmente no puedas usar las herramientas de terceros.
fuente
Esto no es nada sorprendente, pero necesitaba hacer algo como esto hoy y ejecutarlo como una tarea programada, etc.
archivo por lotes, DelFilesOlderThanNDays.bat a continuación con ejemplo de ejecución con parámetros:
fuente
Ampliando la respuesta de aku, veo a muchas personas preguntando sobre los caminos de UNC. Simplemente mapear la ruta unc a una letra de unidad hará felices los archivos. La asignación y la desasignación de unidades se pueden realizar mediante programación en un archivo por lotes, por ejemplo.
Esto eliminará todos los archivos con una extensión .gz que tengan más de 7 días. Si desea asegurarse de que Z: no esté asignado a otra cosa antes de usarlo, puede hacer algo simple como
fuente
La ROBOCOPIA funciona muy bien para mí. Originalmente sugerí mi Iman. ¡Pero en lugar de mover los archivos / carpetas a un directorio temporal y luego eliminar el contenido de la carpeta temporal, mover los archivos a la papelera!
Estas son algunas líneas de mi archivo por lotes de copia de seguridad, por ejemplo:
Limpia cualquier cosa anterior a 15 días de mi carpeta 'Temp' y 30 días para cualquier cosa en mi carpeta de respaldo de AutoCAD. Utilizo variables porque la línea puede ser bastante larga y puedo reutilizarlas para otras ubicaciones. Solo necesita encontrar la ruta de dos a su papelera de reciclaje asociada con su inicio de sesión.
Esto está en una computadora de trabajo para mí y funciona. Entiendo que algunos de ustedes pueden tener derechos más restrictivos, pero de todos modos pruébelo;) Busque explicaciones en Google sobre los parámetros de ROBOCOPY.
¡Salud!
fuente
Mi secuencia de comandos para eliminar archivos anteriores a un año específico:
fuente
Este lo hizo por mí. Funciona con una fecha y puede restar la cantidad deseada en años para retroceder en el tiempo:
el
/F
de lascmd /c del @path /F
fuerzas del archivo específico que desea eliminar en algunos casos el archivo puede ser de sólo lectura.el
dateYear
es la variable año y no se puede cambiar el restar a sus propias necesidadesfuente