Copie arquivos sem sobrescrever

99

Simplesmente não consigo encontrar uma maneira na linha de comando de dizer "copie todos os arquivos do diretório A para o diretório B, mas se o arquivo já existir no diretório B, não o substitua, não importa qual arquivo é mais recente , e não me pergunte. "

Já passei por copiar, mover, xcopy e robocopy, e o mais próximo que posso chegar é que você pode dizer ao robocopy "copiar A para B, mas não sobrescrever arquivos mais novos por arquivos mais antigos", mas isso não funciona para mim . Eu olhei para xxcopy, mas descartei-o, pois não quero ter uma dependência de terceiros em um evento pós-compilação do Visual Studio que exigirá que outros usuários do SVN tenham essa ferramenta instalada para fazer a compilação.

Quero adicionar uma linha de comando ao evento pós-compilação no Visual Studio 2010 para que os arquivos gerados a partir dos modelos T4 para novos objetos de modelo EF sejam distribuídos para as pastas de projeto às quais pertencem, mas arquivos regenerados para objetos existentes não sobrescreva arquivos de destino potencialmente editados.

Uma vez que o modelo T4 é regenerado, o arquivo de origem é sempre mais recente e não posso usar a opção "mais recente" de maneira confiável, não acho.

Eu uso classes parciais para os itens para os quais posso, mas há outras coisas que eu gero que não podem usar classes parciais (por exemplo, gerando um arquivo EditorTemplate ou DisplayTemplate * .ascx padrão).

Alguém já resolveu algum problema semelhante?

Tony
fonte
Você está familiarizado com cmd.exeo forcomando de? Se não, eu recomendo que você execute for /?e use isso.
Gabe

Respostas:

38
For %F In ("C:\From\*.*") Do If Not Exist "C:\To\%~nxF" Copy "%F" "C:\To\%~nxF"
Stu
fonte
5
Isso funcionou para mim, mas tive que usar símbolos de dois por cento em vez de um, pois estava executando isso de dentro de um arquivo em lote, em vez da linha de comando. Substituí instâncias de% F por %% F e instâncias de% ~ nxF por %% ~ nxF.
Owen
1
O que ~nxnos %~nxFsignifica exatamente?
Serge Rogatch
@stu, apenas diz que para ~nxFa variável se Ftransforma em um nome de arquivo e uma extensão.
Serge Rogatch
Sim, de forma eficaz, forneça o nome do arquivo + extensão, sem o caminho - que é o que você precisa para fazer o teste na pasta de destino e especificar o nome do arquivo de destino. A questão é que% F inclui o caminho e você não o quer lá.
Stu
207

Robocopy , ou "Robust File Copy", é um comando de replicação de diretório de linha de comando. Ele está disponível como parte do Windows Resource Kit a partir do Windows NT 4.0 e foi introduzido como um recurso padrão do Windows Vista, Windows 7 e Windows Server 2008.

   robocopy c:\Sourcepath c:\Destpath /E /XC /XN /XO

Para elaborar (usando as respostas Hydrargyrum, HailGallaxar e Andy Schmidt):

  • /E faz o Robocopy copiar recursivamente subdiretórios, incluindo os vazios.
  • /XCexclui arquivos existentes com o mesmo carimbo de data / hora, mas tamanhos de arquivo diferentes. Robocopy normalmente os substitui.
  • /XNexclui arquivos existentes mais recentes do que a cópia no diretório de destino. Robocopy normalmente os substitui.
  • /XOexclui arquivos existentes mais antigos do que a cópia no diretório de destino. Robocopy normalmente os substitui.

Com as classes Changed, Older e Newer excluídas, o Robocopy faz exatamente o que o autor da postagem original deseja - sem precisar carregar um ambiente de script.

Referências: Technet , Wikipedia
Download de: Microsoft Download Link (link verificado pela última vez em 30 de março de 2016)

Dr. belisarius
fonte
Por 'excluir' você quer dizer 'pular' ou 'excluir / remover'?
ataque aéreo de
@Andre Terra: Pule, normalmente. Se você estiver usando o sinalizador / MIR, ele pode removê-los. Eu não testei isso.
Hydrargyrum
Com / MIR, os arquivos que não existem na fonte são realmente removidos. Mas ao usar também / XN e / XO, os arquivos que existem em ambos os locais são simplesmente ignorados (não tenho certeza se o tamanho foi verificado). Isso é ideal para minha situação em que preciso copiar uma versão mais recente ou mais antiga do meu aplicativo, mas onde os carimbos dateModified das bibliotecas que o aplicativo usa estão incorretos, embora os próprios nomes de arquivo contenham seu número de versão.
Henno Vermeulen
É necessário incluir /e? E se você usar em /svez disso? Não quero um monte de subpastas vazias.
Arete
48

A solução de Belisarius é boa.

Para elaborar essa resposta ligeiramente concisa:

  • /E faz o Robocopy copiar recursivamente subdiretórios, incluindo os vazios.
  • /XCexclui arquivos existentes com o mesmo carimbo de data / hora, mas tamanhos de arquivo diferentes. Robocopy normalmente os substitui.
  • /XNexclui arquivos existentes mais novos do que a cópia no diretório de origem. Robocopy normalmente os substitui.
  • /XOexclui arquivos existentes mais antigos que a cópia no diretório de origem. Robocopy normalmente os substitui.

Com as classes Changed, Older e Newer excluídas, o Robocopy faz exatamente o que o autor da postagem original deseja - sem precisar carregar um ambiente de script.

Hydrargyrum
fonte
46

Você pode tentar isto:

echo n | copy /-y <SOURCE> <DESTINATION>

-ysimplesmente solicita antes de sobrescrever e podemos canalizar n para todas essas perguntas. Portanto, em essência, isso seria apenas copiar arquivos não existentes. :)

sachin11
fonte
2
Maravilhosamente simples.
Holf
6
por que ele responde a todas as perguntas quando apenas canalizamos uma vez?
phuclv
Incrível, eu escolhi essa opção. Antes de pensar em tubulação, pesquisei um parâmetro que pensei que estava faltando e então me deparei com esta página. Tentando essa solução, percebi que, ao fazer a tubulação, a cópia aparentemente habilita o parâmetro / Y, por isso / -Y deve ser adicionado.
Andrew
2
@phuclv Parece que copy /-yassume automaticamente Não, uma vez que stdin fica sem entrada. Você pode omitir o primeiro explícito nou canalizar < nulpara ele, e a mesma coisa acontece.
mwfearnley
6

Aqui está em forma de arquivo em lote:

@echo off
set source=%1
set dest=%2
for %%f in (%source%\*) do if not exist "%dest%\%%~nxf" copy "%%f" "%dest%\%%~nxf"
Gabe
fonte
3

Só quero esclarecer algo sobre meu próprio teste.

@Hydrargyrum escreveu:

  • / XN exclui arquivos existentes mais recentes do que a cópia no diretório de origem. Robocopy normalmente os substitui.
  • / XO exclui arquivos existentes mais antigos do que a cópia no diretório de origem. Robocopy normalmente os substitui.

Isso é realmente para trás. O XN "exclui arquivos mais recentes", mas exclui arquivos mais recentes do que a cópia no diretório de destino . O XO "exclui mais antigos", mas exclui arquivos mais antigos do que a cópia no diretório de destino .

Claro, faça seus próprios testes como sempre.

HailGallaxar
fonte
1
Esta é uma resposta à pergunta original ou um comentário sobre a resposta de outra pessoa?
ASGM
1
A resposta de Hydrargyrum que tem +25 votos no momento da redação é uma resposta à pergunta original ou um comentário sobre a resposta de outra pessoa?
mo.
3

Existe uma maneira estranha de fazer isso com xcopy:

echo nnnnnnnnnnn | xcopy /-y source target

Basta incluir tantos n's quantos os arquivos que você está copiando e ele responderá n a todas as perguntas de substituição.

Adam Says - Reintegrar Monica
fonte
Com relação a copy, veja esta resposta , especificamente o comentário @mwfearnley: copy /-yassume automaticamente nquando o stdin é esgotado, então você pode, por exemplo, echo napenas uma vez e ainda funciona.
rsenna
3
robocopy src dst /MIR /XX

/ XX: eXclui arquivos e diretórios "eXtra" (presentes no destino, mas não na origem). Isso impedirá qualquer exclusão do destino. (este é o padrão)

be_good_do_good
fonte
1

Robocopy pode ser baixado aqui para sistemas onde ainda não está instalado. (Ie Windows Server 2003.)

http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17657 (não é necessário reinicializar para instalação)

Lembre-se de definir seu caminho para o exe robocopy. Faça isso clicando com o botão direito em "meu computador"> propriedades> avançado> "Variáveis ​​de ambiente", encontre a variável de sistema do caminho e adicione-a ao final: "; C: \ Arquivos de programas \ Kits de recursos do Windows \ Ferramentas" ou onde você quiser instalado. Certifique-se de deixar as strings da variável de caminho que já estão lá e apenas acrescentar o caminho adicional.

uma vez que o caminho é definido, você pode executar o comando que belisarius sugere. Funciona muito bem.

Greg
fonte
1

Não me deixará comentar diretamente sobre as mensagens incorretas - mas deixe-me apenas avisar a todos, que a definição das opções / XN e / XO são INVERTIDAS em comparação com o que foi postado nas mensagens anteriores.

A opção Excluir arquivos mais antigos / mais recentes é consistente com as informações exibidas no registro do RoboCopy: o RoboCopy irá iterar através da FONTE e então relatar se cada arquivo na FONTE é "MAIS ANTIGO" ou "MAIS NOVO" do que o arquivo no destino.

Conseqüentemente, / XO excluirá arquivos ANTIGA FONTE (o que é intuitivo), não "mais antigo que a fonte", como foi reivindicado aqui.

Se você deseja copiar apenas arquivos de origem novos ou alterados, mas evita substituir arquivos de destino mais recentes, então / XO é a opção correta a ser usada.

Andy Schmidt
fonte
0

Uma abordagem simples seria usar a opção / MIR para espelhar os dois diretórios. Basicamente, ele copiará apenas os novos arquivos para o destino. No próximo comando, substitua a origem e o destino pelos caminhos para suas pastas, o script pesquisará qualquer arquivo com qualquer extensão.

robocopy <source directory> <destination directory> *.* /MIR
Ionut V.
fonte
0

Isso é o que funcionou para mim. Eu uso isso para "adicionar" arquivos à outra unidade, sem sobrescrever.

Arquivo de lote: robocopy-missingfiles.bat

@echo off
echo Copying 
echo      "%1"
echo   to "%2"
echo.
echo Press Cntr+C to abort
Pause
echo.
@echo on
robocopy %1 %2 /Xo /XN /XC /J /SL /S /MT:8 /R:1 /W:1 /V /DCOPY:DAT /ETA /COPY:DATO /FFT /A-:SH /XD $RECYCLE.BIN "System Volume Information"

Exemplo:

robocopy-missingfiles.bat f:\Working-folder\ E:\Backup-folder\

Faça o teste antes da implementação.

Ramesh
fonte