Compare os diretórios, mas não o conteúdo dos arquivos

18

Com o diff -r, eu posso fazer essa tarefa, no entanto demora muito tempo porque o diff verifica o conteúdo do arquivo.

Eu quero algo que determine que dois arquivos são iguais em relação ao tamanho, à última modificação, etc. Mas não é possível verificar bit a bit (por exemplo, um vídeo demora muitíssimo)

Existe alguma outra maneira?

    
por yzT 24.12.2012 / 19:06

6 respostas

16

O rsync, por padrão, compara apenas os metadados do arquivo.

rsync -n -a -i --delete source/ target/

explicação:

  • -n na verdade não copia ou exclui < - ISTO É IMPORTANTE! 1
  • -a compara todos os metadados de arquivo como timestamp e atributos
  • -i imprime uma linha de informação por arquivo
  • --delete também reporta arquivos que não estão na origem

nota: é importante acrescentar os nomes dos diretórios com uma barra. isso é uma coisa de rsync.

se você também quiser ver linhas impressas para arquivos idênticos, forneça -i duas vezes

rsync -n -a -ii --delete source/ target/

exemplo de saída:

*deleting   removedfile   (file in target but not in source)
.d..t...... ./            (directory with different timestamp)
>f.st...... modifiedfile  (file with different size and timestamp)
>f+++++++++ newfile       (file in source but not in target)
.f          samefile      (file that has same metadata. only with -ii)

lembre-se de que o rsync compara apenas metadados. Isso significa que, se o conteúdo do arquivo for alterado, mas os metadados permanecerem os mesmos, o rsync relatará que o arquivo é o mesmo. Este é um cenário improvável. então, confie que, quando os metadados são iguais, os dados são os mesmos ou você precisa comparar os dados do arquivo, pouco a pouco.

bônus: para obter informações sobre o progresso, consulte: Estimativa de tempo ou trabalho para terminar para o rsync?

    
por 07.09.2016 / 02:53
3

Use a opção -q ( --brief ) com diff -r ( diff -qr ). Na página info do GNU diff :

1.6 Summarizing Which Files Differ

When you only want to find out whether files are different, and you don't care what the differences are, you can use the summary output format. In this format, instead of showing the differences between the files, diff' simply reports whether files differ. The--brief' ('-q') option selects this output format.

This format is especially useful when comparing the contents of two directories. It is also much faster than doing the normal line by line comparisons, because 'diff' can stop analyzing the files as soon as it knows that there are any differences.

Isso não irá comparar linha por linha, mas sim o arquivo como um todo, o que acelera bastante o processador (o que você está procurando).

    
por 24.12.2012 / 19:16
2

Aqui está um script python rápido que verificará se os nomes dos arquivos, os tempos e os tamanhos dos arquivos são os mesmos:

import os
import sys

def getStats(path):
    for pathname, dirnames, filenames in os.walk(path):
        for filename in ( os.path.join(pathname, x) for x in filenames ):
            stat = os.stat(filename)
            yield filename[len(path):], stat.st_mtime, stat.st_size

sys.exit(tuple(getStats(sys.argv[1])) != tuple(getStats(sys.argv[2])))
    
por 24.12.2012 / 19:26
0

Baseado no script de Chris Down, esse script é um pouco mais "visual". Chamando-o com dois argumentos folder1 e folder2 , percorre a primeira pasta e para cada arquivo procura um arquivo correspondente na segunda pasta. Se for encontrado, o caminho relativo será impresso em verde, se tiver horário ou tamanho modificado diferente, será impresso em amarelo e, se não for encontrado, será impresso em vermelho.

#!/usr/bin/env python

import os
import sys
from termcolor import colored

def compare_filestats(file1,file2):
    """
    Compares modified time and size between two files.
    Return:
        -1 if file1 or file2 does not exist
         0 if they exist and compare equal
         1 if they have different modified time, but same size
         2 if they have different size, but same modified time
         3 if they have different size, and different modified time
    """

    if not os.path.exists(file1) or not os.path.exists(file2):
        return -1

    stat1 = os.stat(file1)
    stat2 = os.stat(file2)

    return (stat1.st_mtime != stat2.st_mtime) \
        + 2*(stat1.st_size != stat2.st_size)

def compare_folders(folder1,folder2):
    """
    folder1: serves as reference and will be walked through
    folder2: serves as target and will be querried for each file in folder1

    Prints colored status for each file in folder1:
        missing: file was not found in folder2 
        mtime  : modified time is different
        size   : filesize is different
        ok     : found with same filestats
    """
    for dirpath, dirnames, filenames in os.walk(folder1):
        for file1 in ( os.path.join(dirpath, x) for x in filenames ):
            relpath = file1[len(folder1):]
            file2 = os.path.join( folder2, relpath )
            comp = compare_filestats(file1,file2)

            if comp < 0:
                status = colored('[missing]','red')
            elif comp == 1:
                status = colored('[mtime  ]','yellow')
            elif comp >= 2:
                status = colored('[size   ]','yellow')
            else:
                status = colored('[ok     ]','green')

            print status, relpath

if __name__ == '__main__':
    compare_folders(sys.argv[1],sys.argv[2])

Observe que isso é não suficiente para decidir se as duas pastas são as mesmas, você precisaria executá-las nos dois sentidos para ter certeza. Na prática, se você quer apenas saber se as pastas são as mesmas , então o script de Chris é melhor. Se você quiser saber o que está faltando ou diferente de uma pasta para outra , meu script lhe dirá.

NOTA: você precisará do termcolor instalado, pip install termcolor .

    
por 23.08.2016 / 18:29
0

Se você quiser comparar apenas uma estrutura e algumas informações básicas sobre arquivos, tente algo assim:

diff <(cd $DIR1 && ls -laR) <(cd $DIR2 && ls -laR)

Eu não testei, portanto, qualquer edição é bem-vinda:)

    
por 24.12.2012 / 20:03
0

Se você só precisa saber se os arquivos de dois ramos do sistema de arquivos são diferentes (sem olhar dentro dos arquivos), você pode fazer algo assim:

find /opt/branch1 -type f | sort | xargs -i md5sum {} >/tmp/branch1;
find /opt/branch2 -type f | sort | xargs -i md5sum {} >/tmp/branch2;
diff /tmp/branch1 /tmp/branch2;

HTH

    
por 13.12.2018 / 15:33