Encontre e exclua arquivos txt duplicados

1

Eu tenho uma pasta com cerca de 300 arquivos de texto, existe algum comando que lê todos os arquivos individualmente e exclui os arquivos duplicados? Quero dizer, o conteúdo e não os nomes dos arquivos.

    
por DisplayName 30.10.2014 / 17:19

3 respostas

1

Se você tiver fdupes , ele poderá listar todos os arquivos duplicados em sua pasta.

Você pode consultar o este tutorial on-line sobre como usar o comando fdupes .

Teste

Eu criei 3 arquivos chamados arquivo1 , arquivo2 e arquivo3 com arquivo1 e arquivo2 em> tendo exatamente conteúdos semelhantes.

Agora, eu executei meu comando como

fdupes -rdN .

Onde (citando o link acima referido),

  1. A opção r faz com que os fdupes procurem por arquivos recursivamente.
  2. A opção d faz com que os fdupes excluam duplicatas.
  3. A opção N , quando usada junto com d , preserva o primeiro arquivo em cada conjunto de duplicatas e excluir os outros sem solicitar o usuário.

Depois de executar o comando acima, eu tenho arquivo1 e arquivo3 na minha pasta e arquivo2 foi deletado.

    
por 30.10.2014 / 17:24
0

Se o fdupes não estiver disponível, você também pode usar:

for first in *.txt
do
    for second in *.txt
    do
        if  diff $first $second >/dev/null 2>&1 && [ "$first" != "$second" ]
        then
            #echo $first and $second match. Deleting ${second}. # Optional, uncomment to use.
            rm $second
        fi
    done
done 

Nota: isso é muito ineficiente. Ele executará o diff 90.000 vezes para 300 arquivos. Ainda será muito rápido se forem arquivos pequenos, mas podem demorar muito se forem arquivos grandes.

    
por 30.10.2014 / 17:46
0

Como uma resposta secundária, quando o fdupes não está disponível, uma maneira mais eficiente seria usar md5 para obter o hash, e sort e uniq para encontrar duplicatas sem um loop de shell duplo

Algo como: (coloque tudo em uma linha, sem comentários)

find . -type f -name '*.txt'   // get recursively all .txt files
| xargs md5sum         // compute the md5 sum
| awk '{print $2,$1}'  // reverse the md5sum output
| sort -k 2            // sorts on the md5 hash
| uniq --all-repeated=prepend -f 1     // get groups of duplicate files
| awk '/^$/ { I=1 }; /^./ { if (I==0) {print $1} I = 0; }'  // see below
| xargs rm             // delete

excluiria todos os arquivos .txt já encontrados

(Rigorosamente, estou negligenciando o caso de colisões MD5, já que elas não deveriam ocorrer em situações normais.)

Explicando as linhas uniq e awk:

Let's assume :
file1:This is a 1st content
file2:This is a 1st content
file3:This is a 2nd content
file4:This is a 3rd content
file5:This is a 1st content
file6:This is a 3rd content

O resultado da classificação é:

file4 801620325e6bc5efa4333a9413811e23
file6 801620325e6bc5efa4333a9413811e23
file3 8f9722a09b4c6f0ddf867e268193ea1b
file1 a066d80d23803dffa9fbc1cdcd95e163
file2 a066d80d23803dffa9fbc1cdcd95e163
file5 a066d80d23803dffa9fbc1cdcd95e163

uniq --all-repeated=prepend -f 1 mantém apenas duplicatas, precedendo cada bloco com uma linha em branco:

(blank line)
file4 801620325e6bc5efa4333a9413811e23
file6 801620325e6bc5efa4333a9413811e23
(blank line)
file1 a066d80d23803dffa9fbc1cdcd95e163
file2 a066d80d23803dffa9fbc1cdcd95e163
file5 a066d80d23803dffa9fbc1cdcd95e163

Em seguida, um script mini awk ignora as linhas em branco e imprime apenas o primeiro campo de linhas que não seguem uma linha em branco

(--> not printed: blank line)
(--> not printed: file4)
file6
(--> not printed: blank line)
(--> not printed: file1)
file2
file5

Em seguida, um xargs rm pode rm o restante (ou seja, arquivos duplicados)

    
por 30.10.2014 / 19:02