Encontre arquivos duplicados

82

É possível encontrar arquivos duplicados no meu disco, que são pouco a pouco idênticos, mas têm nomes de arquivo diferentes?

    
por student 04.04.2013 / 15:18

7 respostas

99

fdupes pode fazer isso. De man fdupes :

Searches the given path for duplicate files. Such files are found by comparing file sizes and MD5 signatures, followed by a byte-by-byte comparison.

No Debian ou no Ubuntu, você pode instalá-lo com apt-get install fdupes . No Fedora / Red Hat / CentOS, você pode instalá-lo com yum install fdupes . No Arch Linux você pode usar pacman -S fdupes , e no Gentoo, emerge fdupes .

Para executar uma verificação descendente da raiz do sistema de arquivos, o que provavelmente levará uma quantidade significativa de tempo e memória, use algo como fdupes -r / .

Conforme solicitado nos comentários, você pode obter as maiores duplicatas fazendo o seguinte:

fdupes -r . | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n

Isso será interrompido se seus nomes de arquivo contiverem novas linhas.

    
por 04.04.2013 / 15:24
19

Outra boa ferramenta é fslint :

fslint is a toolset to find various problems with filesystems, including duplicate files and problematic filenames etc.

Individual command line tools are available in addition to the GUI and to access them, one can change to, or add to $PATH the /usr/share/fslint/fslint directory on a standard install. Each of these commands in that directory have a --help option which further details its parameters.

   findup - find DUPlicate files

Em sistemas baseados no Debian, você pode instalá-lo com:

sudo apt-get install fslint

Você também pode fazer isso manualmente se não quiser ou não puder instalar ferramentas de terceiros. A maneira como a maioria desses programas funciona é calculando as somas de verificação de arquivos . Arquivos com o mesmo md5sum quase certamente contêm exatamente os mesmos dados. Então, você poderia fazer algo assim:

find / -type f -exec md5sum {} \; > md5sums
gawk '{print $1}' md5sums | sort | uniq -d > dupes
while read d; do echo "---"; grep $d md5sums | cut -d ' ' -f 2-; done < dupes 

Exemplo de saída (os nomes dos arquivos neste exemplo são os mesmos, mas também funcionarão quando forem diferentes):

$ while read d; do echo "---"; grep $d md5sums | cut -d ' ' -f 2-; done < dupes 
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/if_bonding.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/if_bonding.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/linux/route.h
 /usr/src/linux-headers-3.2.0-4-common/include/linux/route.h
---
 /usr/src/linux-headers-3.2.0-3-common/include/drm/Kbuild
 /usr/src/linux-headers-3.2.0-4-common/include/drm/Kbuild
---

Isso será muito mais lento que as ferramentas dedicadas já mencionadas, mas funcionará.

    
por 04.04.2013 / 18:00
8

Resposta curta: sim.

Versão mais longa: dê uma olhada na entrada do fdupes da wikipedia, ela apresenta uma lista bastante interessante de soluções prontas. Claro que você pode escrever o seu próprio, não é que difícil - programas de hashing como diff , sha*sum , find , sort e uniq devem fazer o trabalho. Você pode até colocá-lo em uma linha, e ainda será compreensível.

    
por 04.04.2013 / 15:25
5

Se você acredita que uma função hash (aqui, MD5) está livre de colisões em seu domínio:

find $target -type f -exec md5sum '{}' + | sort | uniq --all-repeated --check-chars=32 \
 | cut --characters=35-

Quer nomes de arquivos idênticos agrupados? Escreva um script simples not_uniq.sh para formatar a saída:

#!/bin/bash

last_checksum=0
while read line; do
    checksum=${line:0:32}
    filename=${line:34}
    if [ $checksum == $last_checksum ]; then
        if [ ${last_filename:-0} != '0' ]; then
            echo $last_filename
            unset last_filename
        fi
        echo $filename
    else
        if [ ${last_filename:-0} == '0' ]; then
            echo "======="
        fi
        last_filename=$filename
    fi

    last_checksum=$checksum
done

Em seguida, altere o comando find para usar seu script:

chmod +x not_uniq.sh
find $target -type f -exec md5sum '{}' + | sort | not_uniq.sh

Esta é uma ideia básica. Provavelmente você deve alterar find se seus nomes de arquivo contiverem alguns caracteres. (por exemplo, espaço)

    
por 13.04.2013 / 17:39
3

Eu pensei em adicionar uma bifurcação aprimorada recente de fdupes, jdupes , que promete ser mais rápida e mais rico em recursos do que fdupes (por exemplo, filtro de tamanho):

jdupes . -rS -X size-:50m > myjdups.txt

Isto irá encontrar recursivamente arquivos duplicados maiores que 50MB no diretório atual e exibir a lista resultante em myjdups.txt.

Note que a saída não é ordenada por tamanho e, como parece não estar incluída, adaptei a resposta @Chris_Down acima para conseguir isso:

jdupes -r . -X size-:50m | {
    while IFS= read -r file; do
        [[ $file ]] && du "$file"
    done
} | sort -n > myjdups_sorted.txt
    
por 23.11.2017 / 18:27
2

A Wikipédia tinha um artigo ( link ), com uma lista de softwares de código aberto disponíveis para essa tarefa, mas agora foi excluído .

Acrescentarei que a versão GUI do fslint é muito interessante, permitindo usar a máscara para selecionar quais arquivos deletar. Muito útil para limpar fotos duplicadas.

No Linux, você pode usar:

- FSLint: http://www.pixelbeat.org/fslint/

- FDupes: https://en.wikipedia.org/wiki/Fdupes

- DupeGuru: https://www.hardcoded.net/dupeguru/

Os últimos 2 trabalhos em muitos sistemas (windows, mac e linux) eu não verifiquei o FSLint

    
por 29.01.2014 / 12:01
0

Aqui está minha opinião sobre isso:

find -type f -size +3M -print0 | while IFS= read -r -d '' i; do
  echo -n '.'
  if grep -q "$i" md5-partial.txt; then echo -e "\n$i  ---- Already counted, skipping."; continue; fi
  MD5='dd bs=1M count=1 if="$i" status=noxfer | md5sum'
  MD5='echo $MD5 | cut -d' ' -f1'
  if grep "$MD5" md5-partial.txt; then echo "\n$i  ----   Possible duplicate"; fi
  echo $MD5 $i >> md5-partial.txt
done

É diferente, pois somente hashes até 1 MB do arquivo.
Isso tem poucos problemas / recursos:

  • Pode haver uma diferença após o primeiro 1 MB, de modo que o resultado seja um candidato a ser verificado. Eu posso consertar isso depois.
  • Verificar primeiro por tamanho de arquivo pode acelerar isso.
  • Só recebe arquivos maiores que 3 MB.

Eu uso para comparar clipes de vídeo, então isso é o suficiente para mim.

    
por 02.06.2017 / 03:50