comparações de arquivos e diretórios com Python

07 Jan 2019

a Biblioteca Padrão Python oferece um poderoso conjunto de ferramentas fora da caixa, incluindo o tratamento de sistemas de arquivos. Neste pequeno artigo rápido, você verá algumas receitas úteis para comparar arquivos e diretórios com o módulo filecmp.

quando você tem uma dolorosa confusão de arquivos e pastas (como aqui, ou aqui), que são difíceis de atravessar, Python é seu amigo para automatizar a pesquisa e comparação. Isto pode então ser combinado com o processamento automático, modificação ou exclusão de arquivos e diretórios em vez de passar manualmente através de cada arquivo.

um aviso justo: verifique e teste sempre o código corretamente ao modificar o sistema de arquivos com qualquer operação como exclusão, renomeação, cópia, entre outros. E também manter várias cópias de seus arquivos importantes “dois é um e um não é nenhum”.

no módulo filecmp encontrará a função cmp() que pode comparar dois ficheiros. Por padrão, a comparação é superficial (shallow=True) o que significa que apenas o SO.Stat () as assinaturas (como tamanho, data modificada,…) de ambos os arquivos são comparadas. Ao definir shallow=False a comparação é feita comparando o conteúdo dos arquivos, o que leva mais tempo. Aqui está um excerto que poderá usar para encontrar todos os duplicados numa pasta:

import osimport itertoolsimport filecmpfiles = os.listdir('path/to/directory')for f1, f2 in itertools.combinations(files, 2): if filecmp.cmp(f1, f2): print(f1, f2)

aqui poderá ver a utilização de outro módulo altamente útil da biblioteca padrão Python, o módulo itertools, que poderá ajudá-lo com vários iteradores e funções de looping. Neste caso, poderá ver a função combinações () que devolve todas as permutações do tamanho 2 da lista de ficheiros. Isto garante que cada arquivo é comparado com o outro arquivo na lista. Para pesquisar recursivamente em todos os ficheiros de uma pasta, substitua files = os.listdir('...') no código anterior por:

files = for (dirpath, dirnames, filenames) in os.walk('.'): for f in filenames: files.append(os.path.join(dirpath, f))

Você também pode comparar diretórios com a classe dircmp. O seguinte excerto passa por duas pastas recursivamente e mostra todos os arquivos que têm o mesmo nome, mas são diferentes e lista todos os arquivos que existem na área de arquivos esquerda ou direita:

import filecmpc = filecmp.dircmp(filepath1, filepath2)def report_recursive(dcmp): for name in dcmp.diff_files: print("DIFF file %s found in %s and %s" % (name, dcmp.left, dcmp.right)) for name in dcmp.left_only: print("ONLY LEFT file %s found in %s" % (name, dcmp.left)) for name in dcmp.right_only: print("ONLY RIGHT file %s found in %s" % (name, dcmp.right)) for sub_dcmp in dcmp.subdirs.values(): print_diff_files(sub_dcmp)report_recursive(c)

Esta é uma ótima maneira se você tiver várias pastas com o mesmo nome, mas você não tem idéia se eles têm o mesmo conteúdo (como diferentes versões de uma pasta de cópia de segurança). Tenha em mente que isso faz apenas uma comparação superficial como você viu na comparação de arquivo antes.