Não é impossível fazer isso com um script em lote. No entanto, o caminho mais fácil é usar RoboCopy
. Infelizmente, isso é incluído apenas no Vista e em versões posteriores, mas os usuários do XP podem instalar o este kit de recursos ou pegue uma cópia independente em outro lugar.
robocopy <source> <destination> /mir
Da ajuda ( robocopy /?
):
/E :: copy subdirectories, including Empty ones.
/PURGE :: delete dest files/dirs that no longer exist in source.
/MIR :: MIRror a directory tree (equivalent to /E plus /PURGE).
Infelizmente, se você não conseguir executar executáveis externos, será necessário um script em lote.
Editar:
No interesse da integralidade, eu escrevi esse script em lote. Apenas certifique-se de testar em um punho de lugar seguro, embora pareça funcionar. Você pode querer remover (ou comentar, coloque um rem
na frente) as linhas del
e rmdir
para testes.
@echo off
setlocal EnableDelayedExpansion
set dirsrc=%~f1
set dirdest=%~f2
echo Source: "%dirsrc%"
echo Destination: "%dirdest%"
echo.
echo.
echo Cleaning files...
for /f "tokens=*" %%a in ('dir /s /b /a:-d "%dirdest%"') do (
set curdest=%%a
set cursrc=!curdest:%dirdest%=%dirsrc%!
if not exist !cursrc! (
echo Deleting "!curdest!"
del "!curdest!"
)
)
echo.
echo.
echo Cleaning directories...
set NLM=^
set NL=^^^%NLM%%NLM%^%NLM%%NLM%
rem Two lines left empty for NewLine to work
for /f "tokens=*" %%a in ('dir /s /b /a:d "%dirdest%"') do (
set curdest=%%a
set cursrc=!curdest:%dirdest%=%dirsrc%!
if not exist !cursrc! (
set rmlist=!curdest!?!rmlist!
)
)
set rmlist=!rmlist:?=%NL%!
for /f "tokens=*" %%a in ("!rmlist!") do (
if exist %%a (
echo Removing directory "%%a"
rmdir "%%a"
)
)
endlocal
O uso é bastante simples: salve como um arquivo .bat (por exemplo, purge.bat) e chame da seguinte forma: purge source destination
. Se você tiver espaços nos caminhos de origem ou de destino, terá que adicionar aspas, como em qualquer outro comando de linha de comando.
Vou explicar brevemente.
Primeiramente, os arquivos são removidos. Ele executa uma substituição de string, substituindo o caminho de destino pelo caminho de origem, para que ele possa verificar se o arquivo existe na origem. Isso me permite informar quais arquivos estão sendo removidos e, quando eu for remover os diretórios, eles estarão vazios. Isso me permite evitar a fealdade de rmdir /s
, que remove todos os subdiretórios e arquivos, o mesmo que rm -r
no Linux. Além disso, distinguir entre um arquivo e um diretório apenas pelo caminho em lote é bastante confuso.
Quando eu removo os diretórios, eu construo uma string em ordem reversa, mantendo todos os caminhos do diretório. É assim que o nível mais profundo é removido primeiro, porque dir /s
sempre fornece os níveis mais profundos por último. Será, no entanto, provavelmente em ordem alfabética inversa.
Além disso, obrigado pelo script basico Eroen, mas não consigo ler o bash;)