Localizando e removendo arquivos duplicados no osx com um script

11

De: http://www.chriswrites.com/2012/02/how-to-find-and-delete-duplicate-files-in-mac-os-x/ Como modifico isso para excluir apenas a primeira versão do o arquivo que vê.

Abra o Terminal no Spotlight ou na pasta Utilitários Altere para o diretório (pasta) em que você deseja pesquisar (incluindo subpastas) usando o comando cd. No prompt de comando, digite cd, por exemplo, cd ~ / Documents para alterar o diretório para sua pasta inicial Documents. No prompt de comando, digite o seguinte comando:

find . -size 20 \! -type d -exec cksum {} \; | sort | tee /tmp/f.tmp | cut -f 1,2 -d ' ' | uniq -d | grep -hif  /tmp/f.tmp > duplicates.txt

Este método usa uma soma de verificação simples para determinar se os arquivos são idênticos. Os nomes dos itens duplicados serão listados em um arquivo chamado duplicates.txt no diretório atual. Abra isso para visualizar os nomes de arquivos idênticos. Agora, existem várias maneiras de excluir as duplicatas. Para excluir todos os arquivos no arquivo de texto, no prompt de comando, digite:

while read file; do rm "$file"; done < duplicates.txt
Jay
fonte

Respostas:

4

Primeiramente, você precisará reordenar a primeira linha de comando para manter a ordem dos arquivos encontrados pelo comando find:

find . -size 20 ! -type d -exec cksum {} \; | tee /tmp/f.tmp | cut -f 1,2 -d   | sort | uniq -d | grep -hif  /tmp/f.tmp > duplicates.txt

(Nota: para fins de teste em minha máquina eu usei find . -type f -exec cksum {} \;)

Em segundo lugar, uma maneira de imprimir tudo, exceto a primeira duplicata, é usando um arquivo auxiliar, digamos /tmp/f2.tmp. Então poderíamos fazer algo como:

while read line; do
    checksum=$(echo "$line" | cut -f 1,2 -d' ')
    file=$(echo "$line" | cut -f 3 -d' ')

    if grep "$checksum" /tmp/f2.tmp > /dev/null; then
        # /tmp/f2.tmp already contains the checksum
        # print the file name
        # (printf is safer than echo, when for example "$file" starts with "-")
        printf %s\\n "$file"
    else
        echo "$checksum" >> /tmp/f2.tmp
    fi
done < duplicates.txt

Apenas verifique se ele /tmp/f2.tmpexiste e está vazio antes de executar isso, por exemplo, através dos seguintes comandos:

rm /tmp/f2.tmp
touch /tmp/f2.tmp

Espero que isso ajude =)

Janito Vaqueiro Ferreira Filho
fonte
39

Outra opção é usar o fdupes:

brew install fdupes
fdupes -r .

fdupes -r .localiza arquivos duplicados recursivamente no diretório atual. Adicionar -dpara excluir as duplicatas - você será perguntado sobre quais arquivos manter; se você adicionar -dN, o fdupes sempre manterá o primeiro arquivo e excluirá outros arquivos.

Lri
fonte
7
fdupesé incrível! Trabalhou como um encanto! Obrigado mano!
precisa
3

Eu escrevi um script que renomeia seus arquivos para corresponder a um hash de seu conteúdo.

Ele usa um subconjunto dos bytes do arquivo, para que seja rápido, e se houver uma colisão, ele adiciona um contador ao nome como este:

3101ace8db9f.jpg
3101ace8db9f (1).jpg
3101ace8db9f (2).jpg

Isso facilita a revisão e a exclusão de duplicatas por conta própria, sem confiar no software de outra pessoa com suas fotos mais do que você precisa.

Script: https://gist.github.com/SimplGy/75bb4fd26a12d4f16da6df1c4e506562

insira a descrição da imagem aqui

SimplGy
fonte
+1 apenas para a exibição GIF !!
NoobEditor 24/05/19
0

Isso é feito com a ajuda do aplicativo EagleFiler, desenvolvido por Michael Tsai .

tell application "EagleFiler"

      set _checksums to {}
      set _recordsSeen to {}
      set _records to selected records of browser window 1
      set _trash to trash of document of browser window 1
      repeat with _record in _records
          set _checksum to _record's checksum
          set _matches to my findMatch(_checksum, _checksums, _recordsSeen)
          if _matches is {} then
              set _checksums to {_checksum} & _checksums
              set _recordsSeen to {_record} & _recordsSeen
          else
              set _otherRecord to item 1 of _matches
              if _otherRecord's modification date > _record's modification date 
then

            set _record's container to _trash
            else
                set _otherRecord's container to _trash
                set _checksums to {_checksum} & _checksums
                set _recordsSeen to {_record} & _recordsSeen
            end if
        end if
    end repeat
end tell

on findMatch(_checksum, _checksums, _recordsSeen)

    tell application "EagleFiler"
        if _checksum is "" then return {}
        if _checksums contains _checksum then
            repeat with i from 1 to length of _checksums
                if item i of _checksums is _checksum then
                    return item i of _recordsSeen
                end if
            end repeat
        end if
        return {}
    end tell

end findMatch

Você também pode excluir automaticamente duplicatas com o removedor de arquivos duplicado sugerido nesta postagem .

Dejise
fonte
1
(1) O que é o "EagleFiler"? Faz parte do macOS? Se não, de onde você tira isso? (2) Isso significa ser um longo bloco de código (da maneira que eu o corrigi)? (3) Por favor, corrija seu recuo. (4) Exatamente como alguém usa isso?
7288 Scott