Como comparar duas pastas recursivamente e gerar uma lista de arquivos e pastas diferentes?

5

tl; dr e um exemplo

Estou procurando uma maneira de comparar recursivamente duas pastas e exibir os caminhos relativos de todos os arquivos (e pastas) que são diferentes (por tamanho ou por timestamp, à la rsync).

Por exemplo, digamos que eu tenha

C:\source\foo\a.txt
C:\source\foo\bar\b.txt
C:\source\foo\bar\c.txt

e

C:\target\foo\a.txt
C:\target\foo\bar\b.txt
C:\target\foo\bar\d.txt
C:\target\foo\baz\

e suponha que b.txt tenha sido alterado em C:\source e seja, portanto, mais recente.

Então, com um script ou comando mágico, digamos, magic C:\source C:\target , gostaria que a saída fosse

foo\bar\b.txt

Ou um caminho completo na pasta de origem ou de destino também seria aceitável:

C:\source\foo\bar\b.txt

Como o exemplo mostra, eu não me importo com arquivos e pastas que foram apagados ou criados! Que deve tornar esta tarefa muito mais simples do que o contrário.

O que eu já conheço ...

Sou eu mesmo um desenvolvedor do UNIX e não estaria perguntando se esse era um sistema UNIX com o qual estamos lidando, mas, infelizmente. Além disso, trata-se de uma solução personalizada de backup noturno, em que a confiabilidade e a integridade dos dados são uma prioridade, de modo que há algumas semanas Eu não conseguia nem descobrir um loop em um script em lote, tenho certeza de que não tenho experiência para fazer isso direito, ou mesmo determinar a melhor maneira de fazer isso.

Lendo link , aprendi que o rsync pode fazer algo parecido com o que eu estou procurando, usando opções como

--dry-run               # don't actually rsync (touch) any files
--itemize-changes       # list changes rsync _would_ have made
--out-format="%i|%n|"   # define an output format for the list of changes

No entanto, eu odiaria confiar no Cygwin (cwRsync) para usar o rsync, já que eu já estou propenso a executar experimentos rápidos e sujos na minha instalação do Cygwin, muitas vezes quebrando o ambiente e precisando reinstalar o Cygwin semanas. Isso se opõe à parte "confiável" de um backup noturno.

Eu não encontrei nenhuma ferramenta "canônica" como o rsync no Windows, pelo menos nenhuma que suporte opções como as acima. Além disso, não estou à procura de software em geral, a menos que seja uma ferramenta simples e compacta para essa finalidade específica Prefiro uma solução programática transparente . Para algo tão importante quanto o backup de arquivos, confiar em software ou código que não posso ver ou entender é assustador!

Recapitular

Eu não consigo entender minha sintaxe de script em lote. Em seguida, vou tentar o PowerShell. Mas o que você faria, dada essa tarefa? - Existe algum caminho óbvio que estou perdendo?

    
por Andrew Cheong 30.04.2014 / 18:28

2 respostas

4

@Glytzhkof recomendou Robocopy em sua resposta, e se adequou perfeitamente às minhas necessidades.

tl; dr

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs

                                C:\source\foo\bar\b.txt

Detalhes & Explicação das opções

Robocopy (Wikipedia) parece ser amplamente adotado para a administração do sistema Windows; é bem documentado (TechNet); é discutido como mais do que uma obscuridade em Stack Overflow , Falha do servidor e, claro, aqui em Super User ; fornece uma função específica em vez de tentar ser uma ferramenta de múltiplos propósitos (que tendem a inchar e bugs); e, além disso, tem fornecido essa função específica desde 1997. Para mim, todos esses fatores contribuem para a "transparência", apesar de ser de código fechado, e me acalmam.

O Robocopy é parte de um conjunto de ferramentas atualmente conhecido como Windows Server 2003 Resource Kit Ferramentas . Depois de fazer o download e instalar, recriou o cenário na minha pergunta e deu uma chance:

C:\>robocopy.exe source target /l /e /zb

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Robust File Copy for Windows
-------------------------------------------------------------------------------

  Started : Thu May 01 09:08:20 2014

   Source : C:\source\
     Dest : C:\target\

    Files : *.*

  Options : *.* /L /S /E /COPY:DAT /ZB /R:1000000 /W:30

------------------------------------------------------------------------------

                           0    C:\source\
                           1    C:\source\foo\
        *EXTRA Dir        -1    C:\target\foo\baz\
                           2    C:\source\foo\bar\
          *EXTRA File                  1        d.txt
            Newer                      5        b.txt
            New File                   1        c.txt

------------------------------------------------------------------------------

               Total    Copied   Skipped  Mismatch    FAILED    Extras
    Dirs :         3         0         3         0         0         1
   Files :         3         2         1         0         0         1
   Bytes :         7         6         1         0         0         1
   Times :   0:00:00   0:00:00                       0:00:00   0:00:00

   Ended : Thu May 01 09:08:20 2014

Parece bom! Deixe-me explicar as opções:

  • /l lista ações sem executá-las.
  • /e inclui subdiretórios, mas ao contrário de /s , também inclui diretórios vazios.
  • /zb de cópias no modo "reinicialização" e, no acesso negado, no modo "backup"; parece a abordagem mais segura; leia mais aqui .

Eu não precisei de nenhuma das opções relacionadas à cópia, pois não estou realmente realizando nenhuma ação.

De qualquer forma, em seguida, foi apenas uma questão de adicionar mais opções para obter a saída desejada:

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs

                                C:\source\foo\bar\b.txt

Mais uma vez, vamos percorrer as opções.

Primeiro, eu só me importei com arquivos e pastas modificados , então:

  • /xx exclui arquivos e diretórios "extras" - aqueles que existem apenas no destino.
  • /xl exclui arquivos e diretórios "solitários" - aqueles que existem apenas na origem.

Em segundo lugar, desejei caminhos relativos (ou pelo menos caminhos completos, não apenas nomes):

  • /fp ativa caminhos completos (sem surpresa, não havia opção para caminhos relativos).

Em terceiro lugar, eu queria remover o máximo possível de registros, e fiquei agradavelmente surpreso ao descobrir que todos eram removíveis:

  • /ns suprime os tamanhos dos arquivos.
  • /nc suprime as classes, por exemplo, Newer .
  • /ndl suprime os nomes dos diretórios.
  • /np suprime a saída do progresso da cópia.
  • /njh suprime o cabeçalho do trabalho.
  • /njs suprime o resumo do trabalho.

E aí está você!

Para minhas finalidades (criação de backups com versão de arquivos alterados), percebi que realmente gostaria de ter o registro de data e hora de cada arquivo modificado também. Basta adicionar /ts :

C:\>robocopy.exe source target /l /e /zb /xx /xl /fp /ns /nc /ndl /np /njh /njs /ts

                         2014/05/01 15:20:42    C:\source\foo\bar\b.txt
    
por 01.05.2014 / 18:27
2

Eu criei um sistema personalizado de backup em lote uma vez que uma ferramenta de terceiros copiava arquivos novos e alterados para uma unidade de backup todas as noites. Para minha vida, não consigo lembrar qual era o nome daquela ferramenta naquele momento. Eu posso encontrar, mas não agora.

A melhor ferramenta de comparação barata e comercial disponível é Além da comparação do link - é de baixo para cima uma ferramenta brilhante. Sua utilidade é imediata e uma ferramenta que todos os profissionais que trabalham com arquivos se beneficiariam todos os dias. Experimente . Veja uma captura de tela . Existe uma versão de linha de comando incluída .

Diferente do que Robocopy.exe deve ser capaz de realizar o que você quer com algum paciência e testes.

Outra dica: para evitar desastres de backup, executei o script de backup com uma conta de baixo privilégio para evitar que ele excluísse qualquer coisa se alguém mexesse no script ou tivesse direitos se alguém tentasse fazer logon com ele. Acho que defini a conta como não interativa ou incapaz de fazer logon interativamente ou algo assim. Altamente recomendo isso para o lote em execução no Windows. Apenas pensei em mencioná-lo, já que você está vindo do mundo do Unix.

    
por 30.04.2014 / 19:28