Desejo excluir um certo número de arquivos mais antigos em uma pasta com .cmd

1

Eu tenho uma pasta de backup onde estão todos os dias uma pasta de backup (como 15.06 .; 14.06; 13.06 .....) contendo os arquivos de backup.

Agora eu quero excluir (no arquivo .cmd) Uma quantidade de x pastas mais antigas para que ainda haja os 30 arquivos mais novos na pasta.

Eu tentei:

set Pf_TargetForfiles=Z:\Backups

set AnzahlOrdner=
for /d %%a in (Z:\TargetForfiles\*) do set /a AnzahlOrdner+=1 

If %AnzahlOrdner% GTR 30 forfiles /p "%Pf_ZielForfiles%" /d -42 /c "CMD /c if @isdir==TRUE rd @path  /s /q"

Saudações

Edit: o que estou testando agora é:

set Pf_ZielBackup=Z:\Backups\F\WichtigVer\Robo\Version\


echo off
Setlocal EnableDelayedExpansion
set "_count=0"
rem count the files
for /f "tokens=*" %%a in ('dir %Pf_ZielBackup% /a:d /b /o:d') do @(set /a _count+=1 >nul) 

echo !_count! directories found
rem delete _count-27 files
for /f "tokens=*" %%a in ('dir %Pf_ZielBackup% /a:d /b /o:d') do (
    set /a _count-=1
    echo directory !_count! is %%a
    echo rd /q %%a

    if "!_count!"=="27" (
      goto :done
    )
  )
:done
pause

Este código tem o - para mim - problema muito estranho que quando eu remover o "eco" de echo rd /q %%a que então eu recebo uma mensagem de erro do windows (O sistema não pode encontrar o especificado Mas se eu executo o script com "echo", ele me lista no prompt de comando dos três arquivos mais antigos, tudo bem. Alguém sabe como consertar isso?

Edit2 Agora O script é executado, mas exclui todas as pastas - eu tive que pará-lo depois que ele excluiu 10 pastas (deveria ter excluído 0) ... no subdiretório - algo com a lógica do contador deve ser errado eu acho:

set Pf_ZielBackup=Z:\Backups\F\WichtigVer\Robo\Version\


echo off
Setlocal EnableDelayedExpansion
set "_count=0"
rem count the files
for /f "tokens=*" %%a in ('dir %Pf_ZielBackup% /a:d /b /o:d') do @(set /a _count+=1 >nul) 

echo !_count! directories found
rem delete _count-30 files
for /f "tokens=*" %%a in ('dir %Pf_ZielBackup% /a:d /b /o:d') do (
    set /a _count-=1
    echo directory !_count! is %Pf_ZielBackup%\%%a
    rd /s /q %Pf_ZielBackup%\%%a


    if "!_count!"=="30" (
      goto :done
    )
  )
:done
pause
    
por user54512 15.06.2015 / 16:03

2 respostas

1

Como Ramhound disse em seu comentário, a maneira mais fácil de atingir esse objetivo é usar o PowerShell. Aqui está um script simples para fazer isso:

$list = Get-ChildItem -Path c:\temp  | Sort-Object LastWriteTime -Descending | Select-Object -Last 10
$list | Remove-Item -Force -WhatIf

Este script irá apagar os 10 arquivos mais antigos na pasta C: \ Temp. Observe que o parâmetro -Whatif permite verificar o que esse comando fará, sem realmente executá-lo. Simplesmente remova este parâmetro quando estiver pronto para executar a operação.

Claro, você pode fazer este script em execução em uma tarefa agendada , assim como você faz com arquivos exe ou em lote.

[UPDATE]: Como o título foi confuso, aqui está a atualização da minha resposta:

$dnd = Get-ChildItem -Path c:\Test -Directory | Sort-Object LastWriteTime -Descending | select -last 2
$list = Get-ChildItem -Path c:\Test -Directory 
$list | Remove-Item -Recurse -Force -Exclude $dnd -WhatIf

Explicações:

  • a variável $ dnd (não excluir) conterá a lista de pastas para manter: no meu exemplo, as 2 mais antigas do diretório C: \ Test;
  • a variável $ list listará todas as pastas em c: \ Test;
  • a terceira linha do script excluirá as pastas com força, excluindo todas as contidas na variável $ dnd . Não se esqueça de remover a opção -WhatIf quando tiver certeza.

Espero que isso ajude!

    
por 15.06.2015 / 16:59
0

Eu quero excluir um certo número de diretórios mais antigos em uma pasta

Você pode usar o seguinte arquivo em lotes:

echo off
Setlocal EnableDelayedExpansion
set "_count=0"
rem count the files
for /f "tokens=*" %%a in ('dir /a:d /b /o:d') do @(set /a _count+=1 >nul)
echo !_count! directories found
rem delete _count-30 files
for /f "tokens=*" %%a in ('dir /a:d /b /o:d') do (
    set /a _count-=1
    echo directory !_count! is %%a
    echo rd /q %%a
    if "!_count!"=="30" (
      goto :done
    )
  )
:done

Como funciona:

  • use for /f com dir para obter uma lista de diretórios
  • % de diretórios/a:d somente
  • use /b para não contarmos . e ..
  • o:d order by date ( mais antigo primeiro)
  • conta os diretórios
  • processe a lista novamente
  • para cada partida diminui a contagem
  • remova a correspondência
  • pare em 30 (deixa 30 diretórios no lugar)

Substitua echo rd /q %%a por rd /q %%a quando terminar de testar o arquivo em lote.

Estou tendo problemas para obter o caminho para o diretório correto

If the path is:

set target=z\backup....

I tried:

for /f "tokens=*" %%a in (%target% /a:d /b /o:d') do....

Sua tentativa está perdendo o caractere dir e o primeiro caractere ' . Deve ser:

for /f "tokens=*" %%a in ('dir %target% /a:d /b /o:d') do ...

Não se esqueça de alterar ambos for /f comandos.

Você também precisa adicionar %target%\ aos dois comandos echo:

echo directory !_count! is %target%\%%a
echo rd /q %target%\%%a
    
por 15.06.2015 / 17:37