Como excluir todos os hardlinks duplicados para um arquivo?

4

Eu tenho uma árvore de diretórios criada por rsnapshot , que contém vários instantâneos da mesma estrutura de diretório com todos os arquivos idênticos substituídos por hardlinks.

Eu gostaria de excluir todas as duplicatas do hardlink e manter apenas uma única cópia de cada arquivo (para que depois eu possa mover todos os arquivos para um arquivo classificado sem ter que tocar em arquivos idênticos duas vezes).

Existe uma ferramenta que faz isso?
Até agora encontrei apenas ferramentas que encontram duplicatas e criam hardlinks para substituí-las…
Eu acho que eu poderia listar todos os arquivos e seus números de inode e implementar a desduplicação e exclusão de mim mesmo, mas não quero reinventar a roda aqui.

    
por n.st 31.05.2016 / 16:21

4 respostas

2

No final, não foi muito difícil fazer isso manualmente, com base em Stéphane e dicas do xenoid e alguma experiência anterior com find .
Eu tive que adaptar alguns comandos para trabalhar com ferramentas não-GNU do FreeBSD - GNU find tem a opção -printf que poderia ter substituído o -exec stat , mas o find do FreeBSD não tem isso.

# create a list of "<inode number> <tab> <full file path>"
find rsnapshots -type f -links +1 -exec stat -f '%i%t%R' {} + > inodes.txt

# sort the list by inode number (to have consecutive blocks of duplicate files)
sort -n inodes.txt > inodes.sorted.txt

# remove the first file from each block (we want to keep one link per inode)
awk -F'\t' 'BEGIN {lastinode = 0} {inode = 0+$1; if (inode == lastinode) {print $2}; lastinode = inode}' inodes.sorted.txt > inodes.to-delete.txt

# delete duplicates (watch out for special characters in the filename, and possibly adjust the read command and double quotes accordingly)
cat inodes.to-delete.txt | while read line; do rm -f "$line"; done
    
por 01.06.2016 / 00:18
2

Para encontrar os inodes que têm mais de um link:

 find . -exec stat -c '%i' {} \; | sort -n | uniq -d

Depois, você pode repetir essa lista com

 find -inum {inode_number}

para listar os arquivos que compartilham o inode. Qual remover é com você.

    
por 31.05.2016 / 16:45
1

Acho que você está enganado, pois acha que excluir todos os "outros" links para um arquivo economizará espaço. O único espaço que você salvará é uma entrada de diretório, e mesmo isso é questionável.

Todos os links para um arquivo são iguais. Não há "duplicatas". Arquivos no Linux são realmente identificados por qual sistema de arquivos eles estão, e qual o número do Inode que eles estão nesse sistema de arquivos.

Então, quando você cria um arquivo, você cria um Inode, onde os blocos realmente vivem, e cria um link para esse arquivo em algum diretório. Esse link apenas aponta para esse inode. Se você fizer um link físico a partir dessa entrada de diretório para outro lugar, basta criar uma segunda entrada de diretório em algum lugar apontando para o mesmo arquivo.

Se você executar ls -i em um arquivo, verá o número do Inode. Se você quiser encontrar outros links para esse mesmo inode, simplesmente execute:

find /TOP-OF-FILESYSTEM -type f -inum INODE-NUMBER

Onde TOP-OF-FILESYSTEM é o ponto de montagem para esse sistema de arquivos, INODE-NUMBER é o número de inode do arquivo em questão. Observe que "-tipo f" não é obrigatório, mas apenas acelera a pesquisa, pois você só procurará arquivos.

Observe que executar ls -il em um arquivo também (por padrão) é o número do inode.

Você pode testar tudo isso acessando um diretório temporário, criando um arquivo e criando outro link para ele:

cd ~/tmp
date > temp1
ln tmep1 temp2
ls -l temp*
    
por 31.05.2016 / 20:39
1

rmlint localizará e removerá as duplicatas, incluindo os links de hardware. No momento, não há opções para remover os hardlinks somente . A remoção é feita por meio de um script de shell gerado automaticamente, para que você possa revisar esse script antes da exclusão.

Em geral, tenha cuidado ao usar detectores de arquivo duplicados no modo de hardlink (por exemplo, fdupes -H), pois eles podem identificar erroneamente um arquivo como sua própria duplicata (consulte "caminho duplicado" discussão aqui ).

    
por 01.06.2016 / 14:38