Estou procurando uma maneira fácil (um comando ou uma série de comandos, provavelmente envolvendo find
) para encontrar arquivos duplicados em dois diretórios e substituí-los em um diretório por links físicos dos arquivos no outro diretório.
Aqui está a situação: Este é um servidor de arquivos no qual várias pessoas armazenam arquivos de áudio, cada usuário tendo sua própria pasta. Às vezes, várias pessoas têm cópias exatamente dos mesmos arquivos de áudio. No momento, essas são duplicatas. Gostaria de fazer com que sejam links físicos, para economizar espaço no disco rígido.
Existe um script Perl em http://cpansearch.Perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl , que faz exatamente o que você deseja:
Percorra todos os diretórios nomeados na linha de comando, calcule as somas de verificação MD5 e localize os arquivos com o MD5 idêntico. Se forem iguais, faça uma comparação real se forem realmente iguais. Substitua o segundo dos dois arquivos por um link físico para o primeiro.
rdfind
faz exatamente o que você pede (e na ordem johny why lista). Torna possível excluir duplicatas, substituí-las por links flexíveis ou físicos. Combinado com symlinks
, você também pode tornar o link simbólico absoluto ou relativo. Você pode até escolher o algoritmo de soma de verificação (md5 ou sha1).
Como é compilado, é mais rápido que a maioria das soluções com script: time
em uma pasta 15 GiB com 2600 arquivos no meu Mac Mini de 2009 retorna isso
9.99s user 3.61s system 66% cpu 20.543 total
(usando MD5).
Disponível na maioria dos manipuladores de pacotes (por exemplo, MacPorts para Mac OS X).
Use a ferramenta fdupes
:
fdupes -r /path/to/folder
fornece uma lista de duplicatas no diretório (-r torna-o recursivo). A saída é assim:
filename1
nome do arquivo2
filename3
nome do arquivo4
nome do arquivo5
com filename1 e filename2 sendo idênticos e filename3, filename4 e filename5 também sendo idênticos.
Eu uso hardlink
de http://jak-linux.org/projects/hardlink/
Esta é uma das funções fornecidas por "fslint" - http://en.flossmanuals.net/FSlint/Introduction
Clique no botão "Mesclar":
Como seu principal objetivo é economizar espaço em disco, existe outra solução: desduplicação (e provavelmente compactação) no nível do sistema de arquivos. Comparado com a solução de link físico, ele não tem o problema de afetar inadvertidamente outros arquivos vinculados.
O ZFS possui desduplicação (em nível de bloco e não de arquivo) desde a versão 23 do pool e compactação há muito tempo. Se você estiver usando o Linux, você pode tentar zfs-Fuse , ou se você usa BSD, ele é suportado nativamente.
Atualmente, no Linux moderno, existem https://github.com/g2p/bedup que desduplica o sistema de arquivos btrfs, mas 1) sem a sobrecarga da verificação, 2) os arquivos podem divergir facilmente novamente depois.
aptitude show hardlink
Descrição: vincula várias cópias do mesmo arquivo ao Hardlink O Hardlink é uma ferramenta que detecta várias cópias do mesmo arquivo e as substitui por links físicos.
A ideia foi tirada de http://code.google.com/p/hardlinkpy/ , mas o código foi escrito do zero e licenciado sob o MIT Homepage: http://jak-linux.org/projects/hardlink/
Para encontrar arquivos duplicados, você pode usar duff.
Duff é um utilitário de linha de comando Unix para encontrar rapidamente duplicatas em um determinado conjunto de arquivos.
Basta executar:
duff -r target-folder
Para criar links automáticos para esses arquivos automaticamente, será necessário analisar a saída de duff com bash ou algum outro script língua.
Eu usei muitas das ferramentas de hardlinking para Linux mencionadas aqui. Eu também estou preso com ext4 fs, no Ubuntu, e tenho usado seus cp -l e - s para hard/softlinking. Mas ultimamente notei a cópia leve na página do manual cp, o que implicaria poupar o espaço em disco redundante até um lado é modificado:
--reflink[=WHEN]
control clone/CoW copies. See below
When --reflink[=always] is specified, perform a lightweight copy, where the
data blocks are copied only when modified. If this is not possible the
copy fails, or if --reflink=auto is specified, fall back to a standard copy.
jdupes
foi mencionado em um comentário, mas merece sua própria resposta, pois provavelmente está disponível na maioria das distribuições e roda muito rápido (ele liberou 2,7 GB de uma partição de 98% de 158 GB (unidade SSD) em aproximadamente um minuto) :
jdupes -rL /foo/bar
Parece-me que verificar o nome do arquivo primeiro pode acelerar as coisas. Se dois arquivos não tiverem o mesmo nome de arquivo, em muitos casos, eu não os consideraria duplicados. Parece que o método mais rápido seria comparar, em ordem:
Algum método faz isso? Veja duff
, fdupes
, rmlint
, fslint
, etc.
O método a seguir foi votado com mais êxito em commandlinefu.com : Localizar arquivos duplicados (com base no tamanho primeiro e depois no hash MD5)
A comparação de nome de arquivo pode ser adicionada como uma primeira etapa, tamanho como uma segunda etapa?
find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | \
xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | \
sort | uniq -w32 --all-repeated=separate
Já que eu não sou fã de Perl, aqui está uma versão do bash:
#!/bin/bash
DIR="/path/to/big/files"
find $DIR -type f -exec md5sum {} \; | sort > /tmp/sums-sorted.txt
OLDSUM=""
IFS=$'\n'
for i in `cat /tmp/sums-sorted.txt`; do
NEWSUM=`echo "$i" | sed 's/ .*//'`
NEWFILE=`echo "$i" | sed 's/^[^ ]* *//'`
if [ "$OLDSUM" == "$NEWSUM" ]; then
echo ln -f "$OLDFILE" "$NEWFILE"
else
OLDSUM="$NEWSUM"
OLDFILE="$NEWFILE"
fi
done
Ele localiza todos os arquivos com a mesma soma de verificação (sejam grandes, pequenos ou já possuem links físicos) e os vincula juntos.
Isso pode ser bastante otimizado para execuções repetidas com sinalizadores de localização adicionais (por exemplo, tamanho) e um cache de arquivo (para que você não precise refazer as somas de verificação a cada vez). Se alguém estiver interessado na versão mais inteligente e mais longa, posso publicá-la.
NOTA: Como mencionado anteriormente, os hardlinks funcionam desde que os arquivos nunca precisem de modificação ou sejam movidos pelos sistemas de arquivos.
Se você deseja substituir duplicatas por Hard Links no mac ou em qualquer sistema UNIX, tente o SmartDupe http://sourceforge.net/projects/smartdupe/ estou desenvolvendo
Eu criei um script Perl que faz algo semelhante ao que você está falando:
Basicamente, ele apenas percorre um diretório, calculando a soma SHA1 dos arquivos, hash e vinculando correspondências. É útil em muitas e muitas ocasiões.
Os aplicativos FSLint ( http://www.pixelbeat.org/fslint/ ) podem encontrar todos os arquivos iguais em qualquer pasta (por conteúdo) e criar links físicos. De uma chance!
Jorge Sampaio
Links físicos podem não ser a melhor ideia; se um usuário altera o arquivo, isso afeta os dois. No entanto, a exclusão de um link físico não exclui os dois arquivos. Além disso, não tenho certeza se os Hard Links ocupam a mesma quantidade de espaço (no disco rígido, não no SO) como várias cópias do mesmo arquivo; de acordo com o Windows (com a Link Shell Extension), eles fazem. Concedido, isso é Windows, não Unix ...
Minha solução seria criar um arquivo "comum" em uma pasta oculta e substituir as duplicatas reais por links simbólicos ... então, os links simbólicos seriam incorporados com metadados ou fluxos de arquivos alternativos que registram apenas os dois "arquivos" são diferentes entre si, como se uma pessoa quisesse alterar o nome do arquivo ou adicionar capas de álbuns personalizadas ou algo parecido; pode até ser útil fora dos aplicativos de banco de dados, como ter várias versões do mesmo jogo ou software instaladas e testá-las independentemente, mesmo com as menores diferenças.
Se você criar hardlinks, preste atenção nos direitos desse arquivo. Aviso, proprietário, grupo, modo, atributos estendidos, hora e ACL (se você usar isso) são armazenados no INODE. Somente nomes de arquivos são diferentes, pois eles são armazenados na estrutura de diretórios e outros apontam para as propriedades INODE. Essa causa, todos os nomes de arquivos vinculados ao mesmo inode, têm os mesmos direitos de acesso. Você deve impedir a modificação desse arquivo, porque qualquer usuário pode danificá-lo para outro. É simples É o suficiente, qualquer usuário coloca outro arquivo com o mesmo nome. O número do inode é salvo e o conteúdo do arquivo original é destruído (substituído) para todos os nomes com links físicos.
Melhor maneira é a desduplicação na camada do sistema de arquivos. Você pode usar BTRFS (muito popular da última vez), OCFS ou assim. Veja a página: https://en.wikipedia.org/wiki/Comparison_of_file_systems , especialmente na tabela Recursos e deduplicação de dados da coluna. Você pode clicar e classificar :)
Veja especialmente o sistema de arquivos ZFS. Está disponível como fusível, mas dessa forma é muito lento. Se você deseja suporte nativo, consulte a página http://zfsonlinux.org/ . Então você deve corrigir o kernel e, em seguida, instalar as ferramentas zfs para gerenciamento. Eu não entendo, por que o linux não suporta como drivers, é o caminho para muitos outros sistemas operacionais/kernels.
Os sistemas de arquivos suportam a desduplicação de duas maneiras, arquivos ou blocos desduplicados. O ZFS suporta bloco. Isso significa que o mesmo conteúdo que se repete no mesmo arquivo pode ser deduplicado. Outra maneira é o momento em que os dados são deduplicados, que podem estar online (zfs) ou offline (btrfs).
Observe que a desduplicação consome RAM. É por isso que gravar arquivos no volume ZFS montado com o Fuse causa desempenho dramaticamente lento. Isso está descrito na documentação. Mas você pode ativar/desativar a deduplicação on-line no volume. Se você vir algum dado que deve ser desduplicado, basta ativar a desduplicação, reescrever algum arquivo para qualquer temporário e finalmente substituí-lo. Depois disso, você pode desativar a desduplicação e restaurar o desempenho total. Obviamente, você pode adicionar ao armazenamento quaisquer discos de cache. Pode ser discos de rotação muito rápida ou discos SSD. Claro que isso pode ser discos muito pequenos. No trabalho real, isso substitui RAM :)
No linux, você deve cuidar do ZFS, porque nem todos funcionam como deveria, principalmente quando você gerencia o sistema de arquivos, faz instantâneos etc. mas se você faz a configuração e não a altera, tudo funciona corretamente. De outro modo, você deve mudar o linux para opensolaris, ele suporta nativamente o ZFS :) O que é muito bom no ZFS é que ele funciona tanto como sistema de arquivos quanto como gerenciador de volumes semelhante ao LVM. Você não precisa disso quando usa o ZFS. Consulte a documentação se você quiser saber mais.
Observe a diferença entre o ZFS e o BTRFS. O ZFS é mais antigo e maduro, infelizmente apenas no Solaris e no OpenSolaris (infelizmente estrangulado pelo Oracle). O BTRFS é mais jovem, mas da última vez é muito bom suportado. Eu recomendo kernel fresco. O ZFS possui desduplicação online, o que causa gravações mais lentas, porque tudo é calculado online. O BTRFS suporta desduplicação offline. Isso economiza desempenho, mas quando o Host não tem nada a fazer, você executa periodicamente a ferramenta para fazer a desduplicação. E o BTRFS é criado nativamente no linux. Talvez seja melhor FS para você :)
A maneira mais fácil é usar o programa especial dupeGuru
como documentação diz
Opções de exclusão
Essas opções afetam como a exclusão duplicada ocorre. Na maioria das vezes, você não precisa ativar nenhum deles.
Vincular arquivos excluídos:
Os arquivos excluídos são substituídos por um link para o arquivo de referência. Você pode substituí-lo por um link simbólico ou um link físico. ... um link simbólico é um atalho para o caminho do arquivo. Se o arquivo original for excluído ou movido, o link está quebrado. Um hardlink é um link para o próprio arquivo. Esse link é tão bom quanto um arquivo "real". Somente quando todos os hardlinks de um arquivo são excluídos, o próprio arquivo é excluído.
No OSX e Linux, esse recurso é totalmente suportado, mas no Windows é um pouco complicado. Windows XP não suporta, mas o Vista e acima. No entanto, para que o recurso funcione, o dupeGuru deve ser executado com privilégios administrativos).