Existe uma maneira fácil de substituir arquivos duplicados por hardlinks?


137

Estou procurando uma maneira fácil (um comando ou uma série de comandos, provavelmente envolvendo find ) de encontrar arquivos duplicados em dois diretórios e substituir os arquivos 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 eles sejam hardlinks, para economizar espaço no disco rígido.


20
Um problema que você pode encontrar com os hardlinks é que, se alguém decidir fazer algo em um dos arquivos de música que você vinculou, eles podem estar inadvertidamente afetando o acesso de outras pessoas à música.
Steven D

4
outro problema é que dois arquivos diferentes que contêm "Some Really Great Tune", mesmo se retirados da mesma fonte com o mesmo codificador, provavelmente não serão idênticos bit a bit.
quer

3
melhor sollution pode ser ter uma pasta música pública ...
Stefan


1
@ante: O uso de links simbólicos não resolve nenhum problema. Quando um usuário "exclui" um arquivo, o número de links para ele é diminuído; quando a contagem chega a zero, os arquivos são realmente excluídos, isso é tudo. Portanto, a exclusão não é um problema com arquivos com links físicos, o único problema é um usuário tentando editar o arquivo (improvável mesmo) ou sobrescrevê-lo (é possível se estiver logado).
Maaartinus 14/03/12

Respostas:


41

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.


Parece perfeito , obrigado !! Vou tentar e aceitar se funcionar como descrito!
Josh

3
Isso fez exatamente o que eu pedi. No entanto, acredito que o ZFS com desduplicação acabará sendo o caminho a ser feito, pois descobri que os arquivos tinham pequenas diferenças, de modo que apenas alguns pudessem ser vinculados.
`

11
Voto positivo, mas depois de pesquisar um pouco mais, eu meio que não o fiz. rdfindestá disponível através dos gerenciadores de pacotes para TODAS as principais plataformas (os x, linux, (cyg) win, solaris) e funciona em uma velocidade nativa escaldante. Então confira a resposta abaixo.
precisa saber é

@ oligofren eu estava pensando o mesmo, mas depois eu bati [Errno 31] Too many links. Este script parece ser a única coisa que lida com isso.
phunehehe

5
A soma de verificação de todos os arquivos, em vez de apenas os arquivos que existem pelo menos um com tamanho idêntico, é desnecessariamente ineficiente (e desnecessariamente propensa a colisões de hash).
Charles Duffy

85

rdfindfaz exatamente o que você pede (e na ordem em que johny lista). Torna possível excluir duplicatas, substituí-las por links flexíveis ou físicos. Combinado comsymlinks você, 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 do que a maioria das soluções com script: timeem uma pasta de 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).


11
+1 eu usei rdfinde adorei. Tem uma -dryrun trueopção que permitirá que você saiba o que teria feito. Substituir duplicatas por links físicos é tão simples quanto -makehardlinks true. Ele produziu um bom log e me informou quanto espaço foi liberado. Além disso, de acordo com a referência do autor , o rdfind é mais rápido que o duff e o fslint.
Daniel Trebbien

oooh legal. Eu costumava usar fdupes, mas sua opção -L para enganar dupes está ausente no Ubuntu 14.10 mais recente. Era bastante lento e não existia para o Homebrew no OSX, então essa resposta é muito melhor. Obrigado!
precisa saber é

Algoritmo muito inteligente e rápido.
Ndemou 30/10/2015

2
Suspeito que o desempenho dessa ferramenta tenha mais a ver com o algoritmo em si e menos a ver se é uma ferramenta compilada ou um script. Para esse tipo de operação, o disco será o gargalo quase o tempo todo. Desde que as ferramentas com script garantam que tenham uma operação de E / S assíncrona em andamento durante a gravação da CPU nas somas de verificação, elas devem ter um desempenho tão bom quanto um binário nativo.
Cdhowie 31/05/19

O rdfind depende muito do novo sistema operacional e compilador. (não será executado no CentOS 6.x sem uma reconstrução quase completa das ferramentas de desenvolvimento)
Cosmo F

49

Use a fdupesferramenta:

fdupes -r /path/to/folderfornece uma lista de duplicatas no diretório (-r o torna recursivo). A saída é assim:


filename1
filename2

filename3
filename4
filename5


com filename1 e filename2 sendo idênticos e filename3, filename4 e filename5 também sendo idênticos.


1
Nota do Ubuntu: Em setembro de 2013, ele não teve uma versão estável (está na 1.50-PR2-3), portanto a atualização ainda não aparece no ubuntu.
Stuart Axon

11
Eu apenas tentei instalar o fdupes_1.50-PR2-4 no Ubuntu e no Debian, nem o sinalizador -L. Felizmente, criar a partir de github.com/tobiasschulz/fdupes foi super fácil.
N

3
Try rdfind- like fdupes, mas mais rápido e disponível no OS X e Cygwin também.
precisa saber é

6
fdupesparece encontrar apenas duplicatas, não substituí-las por hardlinks; portanto, não é uma resposta para a pergunta IMO.
Calimo 8/11

2
Existe uma ferramenta semelhante chamada jdupesque é baseada fdupes, mas também pode substituir os arquivos duplicados por symlinks ( -l), hardlinks ( -L) ou instruir o btrfs a deduplicar os blocos no nível do sistema de arquivos ( -Bse você estiver usando o btrfs).
Marius Gedminas

23

1
Boa dica, estou usando em uma base regular, code.google.com/p/hardlinkpy mas isso não foi atualizado por um tempo ...
meduz

2
Parece ser semelhante ao original hardlinkno Fedora / RHEL / etc.

1
hardlinkagora é um binário nativo em muitos sistemas de pacotes Linux (desde ~ 2014) e extremamente rápido. Para arquivos de 1,2 milhões (320 GB), foram necessários apenas 200 segundos (vinculando aproximadamente 10% dos arquivos).
Marcel Waldvogel

FWIW, o acima hardlinkfoi criado por Julian Andres Klode enquanto o Fedora hardlinkfoi criado por Jakub Jelinek (fonte: pagure.io/hardlink - nome do pacote Fedora: hardlink)
maxschlepzig

18

Esta é uma das funções fornecidas por "fslint" - http://en.flossmanuals.net/FSlint/Introduction

Clique no botão "Mesclar":

Captura de tela


4
O -m vai hardlink duplicatas juntos, -d irá apagar todos, mas um, e -t vai secar prazo, a impressão que ele faria
Azendale

1
No Ubuntu aqui é o que fazer: sudo apt-get install fslint /usr/share/fslint/fslint/findup -m /your/directory/tree(diretório / usr / share / fslint / fslint / não está na $ PATH por padrão)
Jocelyn

14

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, tente o zfs-fuse ou, se usar o BSD, ele será suportado nativamente.


Este é provavelmente o caminho a seguir, no entanto, a implementação do BSD no ZFS faz a desduplicação? Eu pensei que não.
Josh

Além disso, o sistema de arquivos HAMMER no DragonFlyBSD possui suporte à desduplicação.
Hhamam

14
A dedup do ZFS não é amiga de ninguém. Onde o ZFS recomenda 1 GB de RAM por 1 TB de espaço em disco utilizável, você fica louco se tentar usar a desduplicação com menos de 32 GB de RAM por 1 TB de espaço em disco utilizável. Isso significa que, para um espelho de 1 TB, se você não possui 32 Gb de ram, é provável que encontre condições de bomba de memória, mais cedo ou mais tarde, que interromperão a máquina devido à falta de ram. Estive lá, fiz isso, ainda me recuperando do TEPT.
Killermist #

4
Para evitar os requisitos excessivos de RAM com a desduplicação online (ou seja, verificar todas as gravações ), btrfsusa a desduplicação em lote ou offline (execute-a sempre que considerar útil / necessária) btrfs.wiki.kernel.org/index.php/Deduplication
Marcel Waldvogel

3
Atualização sete anos depois: eu finalmente mudei para o ZFS e tentei a desduplicação - descobri que os requisitos de RAM eram realmente muito altos. O uso astuto de instantâneos do ZFS forneceu a solução que acabei usando. (Copie um usuário de música, instantâneo e clone, copiar música do segundo usuário no clone usando rsync --inplacetão somente blocos alterados são armazenados)
Josh


5

Para encontrar arquivos duplicados, você pode usar o 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, você precisará analisar a saída do duff com o bash ou alguma outra linguagem de script.


Muito lento, porém - consulte rdfind.pauldreik.se/#g0.6
ndemou

5
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 retirada de http://code.google.com/p/hardlinkpy/ , mas o código foi escrito do zero e licenciado sob a licença MIT. Página inicial: http://jak-linux.org/projects/hardlink/


O único programa mencionado aqui disponível para o Gentoo sem desmascarar e com suporte a hardlink, obrigado!
Jorrit Schippers

4

Eu usei muitas das ferramentas de hardlinking para Linux mencionadas aqui. Eu também estou preso ao 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 de manual do cp , o que implicaria em poupar espaço em disco redundante até que um lado fosse 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.

Acho que vou atualizar meu cpalias para sempre incluir o --reflink=autoparâmetro agora
Marcos

1
O ext4 realmente suporta --reflink?

7
Isso é suportado no btrfs e no OCFS2. Só é possível em sistemas de arquivos copiar-em-gravar, o que ext4 não é. O btrfs está realmente se moldando. Adoro usá-lo por causa do reflink e instantâneos, deixa você com menos medo de fazer operações em massa em grandes árvores de arquivos.
Clacke

3

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:

  • nome do arquivo
  • Tamanho
  • soma de verificação md5
  • conteúdo de bytes

Algum método faz isso? Olhe 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

3
Eu usei duff, fdupese rmlint, e recomendo fortemente os leitores a olhar para a terceira delas . Possui um excelente conjunto de opções (e documentação). Com isso, pude evitar grande parte do pós-processamento necessário para usar com as outras ferramentas.
dubiousjim

3
Na minha prática, o nome do arquivo é o fator menos confiável de se olhar, e eu o removi completamente de todos os esforços que eu faço para desiludir. Quantos install.sharquivos podem ser encontrados em um sistema ativo? Não consigo contar o número de vezes que salvei um arquivo e tive um conflito de nome, com algumas renomeações dinâmicas para salvá-lo. Outro lado: não faço ideia de quantas vezes baixei algo de fontes diferentes, em dias diferentes, apenas para descobrir que eles têm o mesmo arquivo com nomes diferentes. (O que também reduz a confiabilidade do registro de data e hora.) 1: Tamanho, 2: Resumo, 3: Conteúdo de bytes.
Gypsy Spellweaver

@ GypsySpellweaver: (1) depende do caso de uso pessoal, você não concorda? No meu caso, tenho várias restaurações de vários backups, onde arquivos com o mesmo nome e conteúdo existem em diferentes pastas de restauração. (2) Seu comentário parece assumir apenas a comparação do nome do arquivo . Eu não estava sugerindo eliminar outros cheques.
johny why

2

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.


Como posso alterar seu script, para que, em vez de vinculá-lo, ele apague os arquivos duplicados e adicione uma entrada a um arquivo CSV: o arquivo excluído -> Arquivo alinhado. . ???
MR.GEWA

Certo. A linha do link físico: echo ln -f "$ OLDFILE" "$ NEWFILE" Apenas substitui o arquivo duplicado por um link físico, para que você possa alterá-lo pelo $ NEWFILE.
seren

e como na próxima linha, escreva em algum arquivo de texto de alguma forma $ OLDFILE-> NEWFILE ???
MR.GEWA

Ahh, certo. Sim, adicione uma linha após a rm, como: echo "$ NEWFILE" >> /var/log/deleted_duplicate_files.log
seren

2
Não comece a reinventar a roda. Existem soluções mais maduras disponíveis, rdfindque funcionam em velocidades nativas e requerem apenas brew install rdfindou apt-get install rdfindpara serem instaladas.
precisa saber é

1

Eu criei um script Perl que faz algo semelhante ao que você está falando:

http://pastebin.com/U7mFHZU7

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.


2
Espero começar a tentar isso em breve ... por que não carregá-lo no CPAN ... App :: relink or something
xenoterracide

2
@xenoterracide: por causa de todas as soluções semelhantes e mais maduras que já existem. veja as outras respostas, especialmente rdfind.
precisa saber é

1
@oligofren Não duvido que existam melhores soluções. TMTOWTDI eu acho.
Amphetamachine


1

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


Ele trava a digitalização de 1 TB de disco rígido ext3 quase completo, traz todo o sistema para um rastreamento. Abortada após 14 horas de "pesquisar"
Angsuman Chakraborty

1

jdupes foi mencionado em um comentário, mas merece sua própria resposta, já que 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 cerca de um minuto):

jdupes -rL /foo/bar

0

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 FUSE, mas dessa maneira é 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 oferecem suporte à desduplicação de 2 maneiras, arquivos ou 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 a gravação de arquivos no volume ZFS montado com o FUSE causa um 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 a RAM :)

No linux, você deve cuidar do ZFS, porque nem todos funcionam como deveriam, especialmente 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 outra forma, 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ê :)


1
Eu gosto da abordagem de desduplicação offline (ou em lote ) btrfs. Excelente discussão sobre as opções (incluindo a cp --reflinkopção) aqui: btrfs.wiki.kernel.org/index.php/Deduplication
Marcel Waldvogel

O ZFS não é apenas Solaris ou OpenSolaris. É suportado nativamente no FreeBSD. Além disso, o ZFS no Linux é baseado em driver de dispositivo; O ZFS no FUSE é uma coisa diferente.
KJ Seefried

0

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.


0

A maneira mais fácil é usar o programa especial dupeGuru

Captura de tela das preferências do dupeGuru

como a 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. O Windows XP não suporta, mas o Vista e versões superiores suportam. No entanto, para que o recurso funcione, o dupeGuru precisa ser executado com privilégios administrativos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.