Estou procurando uma maneira de excluir todos os arquivos com mais de 7 dias em um arquivo em lotes. Pesquisei na web e encontrei alguns exemplos com centenas de linhas de código e outros que exigiam a instalação de utilitários extras de linha de comando para realizar a tarefa.
Coisas semelhantes podem ser feitas no BASH em apenas algumas linhas de código. Parece que algo pelo menos remotamente fácil poderia ser feito para arquivos em lote no Windows. Estou procurando uma solução que funcione em um prompt de comando padrão do Windows, sem utilitários extras. Por favor, não PowerShell ou Cygwin também.
Respostas:
Aproveitar:
Veja a
forfiles
documentação para mais detalhes.Para mais guloseimas, consulte Um índice AZ da linha de comando do Windows XP .
Se você não tiver
forfiles
instalado em sua máquina, copie-o de qualquer Windows Server 2003 para sua máquina Windows XP em%WinDir%\system32\
. Isso é possível, pois o EXE é totalmente compatível entre o Windows Server 2003 e o Windows XP.Versões posteriores do Windows e Windows Server o instalam por padrão.
Para Windows 7 e mais recente (incluindo Windows 10):
A sintaxe mudou um pouco. Portanto, o comando atualizado é:
fonte
Execute os seguintes comandos :
Mova todos os arquivos (usando / mov, que move arquivos e os exclui, em oposição a / move, que move arquivos de arquivos inteiros que são excluídos) via robocopy para outro local e, em seguida, execute um comando de exclusão nesse caminho e pronto. Boa.
Além disso, se você tiver um diretório com muitos dados, poderá usar o
/mir
switchfonte
rd /s /q c:\destination
odel
comando em vez do comando ou mesmo outrarobocopy /mir c:\emptydir c:\destination
execução para esvaziar o diretório se você espera problemas com os nomes dos arquivos.forfiles
da resposta aceita, não serve .C:\test
mais de 7 dias. Para excluir os arquivos, altereecho
paradel
:forfiles /p "C:\test" /m "*.*" /c "cmd /c echo @file" /D -7
Ok ficou um pouco entediado e surgiu com isso, que contém a minha versão da substituição de época do pobre homem Linux limitada para uso diário (sem retenção de tempo):
7daysclean.cmd
USO
set /a strip=day*7
: Altere 7 para o número de dias a serem mantidos.set dSource=C:\temp
: Este é o diretório inicial para procurar arquivos.NOTAS
Este é um código não destrutivo, exibirá o que teria acontecido.
Mudança :
para algo como:
para que os arquivos sejam realmente excluídos
Fevereiro : é codificado para 28 dias. Anos bissextos são um inferno a acrescentar, na verdade. se alguém tiver uma idéia que não adicione 10 linhas de código, vá em frente e poste, então eu a adiciono ao meu código.
época : não levei muito tempo em consideração, pois a necessidade é excluir arquivos anteriores a uma determinada data; levar horas / minutos teria excluído os arquivos de um dia destinado a ser mantido.
LIMITAÇÃO
época assume como certo que o seu formato de data curta é AAAA-MM-DD. Ele precisaria ser adaptado para outras configurações ou para uma avaliação em tempo de execução (leia sShortTime, configuração vinculada ao usuário, configure a ordem de campo adequada em um filtro e use o filtro para extrair os dados corretos do argumento).
Eu mencionei que odeio a formatação automática deste editor? remove as linhas em branco e a copiar e colar é um inferno.
Eu espero que isso ajude.
fonte
7daysclean.cmd
soa como um nome incrível para uma banda de Synth-Punk.Você deve fazer
/d -3
(3 dias antes) Isso funciona bem para mim. Portanto, todos os lotes complicados podem estar na lixeira. Tambémforfiles
não suporta caminhos UNC; portanto, faça uma conexão de rede com uma unidade específica.fonte
*.*
? O curinga*.*
não corresponde a todos os arquivos no Windows. Ele corresponde apenas aos arquivos.
em seus nomes. O OP nunca disse nada sobre a exigência.
no nome do arquivo. O parâmetro apropriado é/M *
, mas esse é o padrão de qualquer maneira. Não é necessário/M
.*.*
se comporta exatamente como*
no Windows. Na verdade, eu apenas tentei no meu computador e, nadir *.*
verdadetest file
, listei um arquivo sem extensão.*.*
é inconsistente entre, digamos,dir
e a-m
opção deforfiles
. A-m *.*
máscara realmente ignorará nomes de arquivos sem extensão, como afirmei no meu comentário acima (tente você mesmo). A parte engraçada aqui é que a documentação da MS afirma explicitamente que-m *.*
é o padrão. No entanto, se você tentar na vida real, verá que o padrão é realmente-m *
- todos os arquivos são iterados.*.*
máscara era aplicada para todos os arquivos. Minha pergunta retórica sobre "esse estranho hábito" foi de fato desnecessária, uma vez que tratar*.*
e*
como equivalente é uma convenção antiga do Windows. No entanto, a/m
opção inforfiles
viola essa convenção por algum motivo.Dê uma olhada na minha resposta para uma pergunta semelhante :
Isso exclui arquivos anteriores a uma determinada data. Tenho certeza de que pode ser modificado para voltar sete dias a partir da data atual.
atualização: Percebo que o HerbCSO melhorou no script acima. Eu recomendo usar a versão dele .
fonte
Meu comando é
@PATH
- é apenas caminho no meu caso, então eu tive que usar@PATH\@FILE
também
forfiles /?
não está funcionando para mim também, masforfiles
(sem "?") funcionou bem.E a única pergunta que tenho: como adicionar várias máscaras (por exemplo " .log | .bak")?
Tudo isso sobre o forfiles.exe que eu baixei aqui (no win XP)
Mas se você estiver usando o servidor do Windows, o forfiles.exe já deve estar lá e difere da versão ftp. É por isso que devo modificar o comando.
Para o Windows Server 2003, estou usando este comando:
fonte
Muitas vezes, existem questões relacionadas a data / hora relativas a serem resolvidas com o arquivo em lote. Mas o interpretador de linha de comando cmd.exe não tem função para cálculos de data / hora. Muitas boas soluções de trabalho usando scripts ou aplicativos de console adicionais já foram postadas aqui, em outras páginas do Stack Overflow e em outros sites.
Comum para operações baseadas em data / hora é o requisito de converter uma sequência de data / hora em segundos desde um determinado dia. Muito comum é 1970-01-01 00:00:00 UTC. Mas qualquer dia posterior também pode ser usado, dependendo do período necessário para dar suporte a uma tarefa específica.
Jay postou 7daysclean.cmd contendo uma solução rápida de "data para segundos" para o interpretador de linha de comando cmd.exe . Mas não leva em consideração os anos bissextos corretos. JR postou um complemento por considerar o dia bissexto no ano corrente, mas ignorando os outros anos bissextos desde o ano base, ou seja, desde 1970.
Uso há 20 anos tabelas estáticas (matrizes) criadas uma vez com uma pequena função C para obter rapidamente o número de dias, incluindo os dias bissextos de 01-01-2009 nas funções de conversão de data / hora em meus aplicativos escritos em C / C ++.
Esse método de tabela muito rápido também pode ser usado no código de lote usando o comando FOR . Por isso, decidi codificar a sub-rotina em lote
GetSeconds
que calcula o número de segundos desde 1970-01-01 00:00:00 UTC para uma sequência de data / hora passada para essa rotina.Nota: Os segundos bissextos não são levados em consideração, pois os sistemas de arquivos do Windows também não suportam segundos bissextos.
Primeiro, as tabelas:
Dias desde 1970-01-01 00:00:00 UTC para cada ano, incluindo os dias bissextos.
O cálculo dos segundos para o ano 2039 a 2106 com a época começando em 01-01-2009 só é possível com o uso de uma variável de 32 bits não assinada, ou seja, sem assinatura longa (ou sem assinatura int) em C / C ++.
Mas o cmd.exe usa para expressões matemáticas uma variável de 32 bits assinada. Portanto, o valor máximo é 2147483647 (0x7FFFFFFF), que é 2038-01-19 03:14:07.
Informações sobre o ano bissexto (Não / Sim) para os anos de 1970 a 2106.
Número de dias para o primeiro dia de cada mês no ano atual.
Converter uma data em um número de segundos desde 01-01-2009 é bastante fácil usando essas tabelas.
Atenção por FAVOR!
O formato das seqüências de data e hora depende das configurações de idioma e região do Windows. Os delimitadores e a ordem dos tokens atribuídos às variáveis de ambiente e
Day
, no primeiro loop FOR, devem ser adaptados ao formato local de data / hora, se necessário.Month
Year
GetSeconds
É necessário adaptar a sequência de datas da variável de ambiente se o formato de data na variável de ambiente DATE for diferente do formato de data usado pelo comando FOR ativado
%%~tF
.Por exemplo, quando
%DATE%
expande paraSun 02/08/2015
enquanto%%~tF
expande para02/08/2015 07:38 PM
o código abaixo, pode ser usado com a modificação da linha 4 para:Isso resulta na passagem para a sub-rotina just
02/08/2015
- a sequência de datas sem as três letras da abreviação do dia da semana e o caractere de espaço separador.Como alternativa, pode-se usar o seguinte para passar a data atual no formato correto:
Agora, os últimos 10 caracteres da sequência de datas são passados para a função
GetSeconds
e, portanto, não importa se a sequência de datas da variável de ambiente DATE está com ou sem dia da semana, desde que dia e mês estejam sempre com 2 dígitos na ordem esperada, ou seja, no formatodd/mm/yyyy
oudd.mm.yyyy
.Aqui está o código do lote com a explicação dos comentários que apenas gera qual arquivo excluir e qual arquivo manter na
C:\Temp
árvore de pastas, consulte o código do primeiro loop FOR .Para um desempenho ideal, seria melhor remover todos os comentários, ou seja, todas as linhas começando com rem após 0-4 espaços à esquerda.
E as matrizes também podem ser menores, ou seja, diminuindo o período de 1980-01-01 00:00:00 para 2038-01-19 03:14:07 conforme atualmente suportado pelo código de lote acima, por exemplo, para 2015-01 -01 a 2019-12-31, como o código abaixo usa, que realmente exclui arquivos com mais de 7 dias na
C:\Temp
árvore de pastas.Além disso, o código do lote abaixo é otimizado para o formato de 24 horas.
Para obter mais informações sobre formatos de data e hora e comparações de horário de arquivo no Windows, consulte minha resposta em Descubra se o arquivo tem mais de 4 horas no arquivo em lotes com muitas informações adicionais sobre horários de arquivo.
fonte
Copie esse código e salve-o como
DelOldFiles.vbs
.USO EM CMD:
cscript //nologo DelOldFiles.vbs 15
15 significa excluir arquivos com mais de 15 dias no passado.
fonte
Para o Windows Server 2008 R2:
Isso excluirá todos os arquivos .sql com mais de 90 dias.
fonte
Use forfiles.
Existem versões diferentes. Os primeiros usam parâmetros de estilo unix.
Minha versão (para servidor 2000 - observe que não há espaço após as opções) -
Para adicionar forfiles ao XP, obtenha o exe em ftp://ftp.microsoft.com/ResKit/y2kfix/x86/
e adicione-o a C: \ WINDOWS \ system32
fonte
*.*
emforfiles
não corresponder todos os arquivos. Ele corresponde apenas aos arquivos.
em seus nomes (ou seja, arquivos com extensões). O OP nunca disse nada sobre a exigência.
no nome do arquivo. O parâmetro apropriado é/M *
, mas esse é o padrão de qualquer maneira. Não é necessário/M
.Para o Windows 2012 R2, o seguinte funcionaria:
para ver os arquivos que serão excluídos, use este
fonte
Na IMO, o JavaScript está gradualmente se tornando um padrão de script universal: provavelmente está disponível em mais produtos do que em qualquer outra linguagem de script (no Windows, está disponível usando o Windows Scripting Host). Eu tenho que limpar arquivos antigos em muitas pastas, então aqui está uma função JavaScript para fazer isso:
Para que cada pasta seja limpa, basta adicionar outra chamada à função clearFolder (). Esse código específico também preserva os arquivos exe e dll e limpa as subpastas também.
fonte
Que tal essa modificação no 7daysclean.cmd para levar em consideração um ano bissexto?
Isso pode ser feito em menos de 10 linhas de codificação!
Editar por Mofi:
A condição acima contribuída por JR é sempre avaliada como falsa devido à sintaxe inválida.
E
Month GEQ 2
também está errado porque a adição de 86400 segundos por mais um dia deve ser feita em um ano bissexto apenas nos meses de março a dezembro, mas não em fevereiro.Um código de trabalho para levar em consideração o dia bissexto - apenas no ano atual - no arquivo em lote 7daysclean.cmd publicado por Jay seria:
fonte
Posso acrescentar uma contribuição humilde a esse segmento já valioso. Estou descobrindo que outras soluções podem se livrar do texto de erro real, mas estão ignorando o% ERRORLEVEL% que sinaliza uma falha no meu aplicativo. E eu legitimamente quero% ERRORLEVEL% desde que não seja o erro "Nenhum arquivo encontrado".
Alguns exemplos:
Depurando e eliminando o erro especificamente:
Usando um oneliner para retornar ERRORLEVEL com êxito ou falha:
Usando um oneliner para manter o ERRORLEVEL em zero para obter sucesso no contexto de um arquivo em lote no meio de outro código (ver> nul redefine o ERRORLEVEL):
Para uma etapa do trabalho CmdExec do SQL Server Agent, cheguei ao seguinte. Não sei se é um erro, mas o CmdExec na etapa reconhece apenas a primeira linha de código:
fonte
Caramba, muitas respostas já. Uma rota simples e conveniente que encontrei foi executar o ROBOCOPY.EXE duas vezes em ordem sequencial a partir de uma única instrução de linha de comando do Windows usando o parâmetro & .
Neste exemplo, ele funciona escolhendo todos os arquivos ( . ) Com mais de 30 dias e movendo-os para a pasta de destino. O segundo comando faz o mesmo novamente com a adição do comando PURGE, o que significa remover arquivos na pasta de destino que não existem na pasta de origem. Portanto, essencialmente, o primeiro comando MOVE arquivos e o segundo DELETE porque eles não existem mais na pasta de origem quando o segundo comando é chamado.
Consulte a documentação do ROBOCOPY e use a opção / L ao testar.
fonte
Se você tiver o kit de recursos do XP, poderá usar o robocopy para mover todos os diretórios antigos em um único diretório e, em seguida, use o rmdir para excluir apenas um:
fonte
Acho que a resposta do e.James é boa, pois funciona com versões não modificadas do Windows desde o Windows 2000 SP4 (e possivelmente anterior), mas era necessário gravar em um arquivo externo. Aqui está uma versão modificada que não cria um arquivo de texto externo, mantendo a compatibilidade:
Para ser fiel à pergunta original, aqui está um script que faz TODAS as contas para você, se você o chamar com o número de dias como parâmetro:
NOTA: O código acima leva em consideração os anos bissextos, bem como o número exato de dias em cada mês. O único máximo é o número total de dias desde 0/0/0 (depois disso, retorna anos negativos).
OBSERVAÇÃO: A matemática é apenas uma maneira; não é possível obter corretamente datas futuras com informações negativas (tentará, mas provavelmente passará o último dia do mês).
fonte
Você pode conseguir isso. Você pode dar uma olhada nesta pergunta , para um exemplo mais simples. A complexidade vem quando você começa a comparar as datas. Pode ser fácil dizer se a data é maior ou não, mas há muitas situações a serem consideradas se você realmente precisar obter a diferença entre duas datas.
Em outras palavras - não tente inventar isso, a menos que você realmente não possa usar as ferramentas de terceiros.
fonte
isso não é nada surpreendente, mas eu precisava fazer algo parecido hoje e executá-lo como tarefa agendada etc.
arquivo em lote, DelFilesOlderThanNDays.bat abaixo, com exemplo de execução com parâmetros:
fonte
Expandindo a resposta do aku, vejo muitas pessoas perguntando sobre os caminhos UNC. O simples mapeamento do caminho unc para uma letra de unidade fará com que os arquivos sejam felizes. O mapeamento e o mapeamento de unidades podem ser feitos programaticamente em um arquivo em lotes, por exemplo.
Isso excluirá todos os arquivos com uma extensão .gz com mais de 7 dias. Se quiser garantir que o Z: não esteja mapeado para mais nada antes de usá-lo, você pode fazer algo simples como
fonte
O ROBOCOPY funciona muito bem para mim. Originalmente sugeriu meu Iman. Mas, em vez de mover os arquivos / pastas para um diretório temporário e excluir o conteúdo da pasta temporária, mova os arquivos para o lixo !!!
Esta é algumas linhas do meu arquivo em lotes de backup, por exemplo:
Ele limpa qualquer coisa com mais de 15 dias da minha pasta 'Temp' e 30 dias para qualquer coisa na minha pasta de backup do AutoCAD. Uso variáveis porque a linha pode ficar bastante longa e posso reutilizá-las para outros locais. Você só precisa encontrar o caminho dos para sua lixeira associada ao seu login.
Este é um computador de trabalho para mim e funciona. Entendo que alguns de vocês podem ter direitos mais restritivos, mas tente de qualquer maneira;) Pesquise no Google explicações sobre os parâmetros do ROBOCOPY.
Felicidades!
fonte
Meu script para excluir arquivos anteriores a um ano específico:
fonte
Este fez isso por mim. Ele funciona com uma data e você pode subtrair a quantia desejada em anos para voltar no tempo:
o
/F
nocmd /c del @path /F
forças o arquivo específico a ser eliminado em alguns casos, o arquivo pode ser somente leitura.o
dateYear
é o ano variável e aí você pode alterar o substrato de acordo com suas próprias necessidadesfonte