Encontrar y eliminar archivos duplicados en osx con un script

11

De: http://www.chriswrites.com/2012/02/how-to-find-and-delete-duplicate-files-in-mac-os-x/ ¿Cómo modifico esto para eliminar solo la primera versión de el archivo que ve

Abra Terminal desde Spotlight o la carpeta Utilidades Cambie al directorio (carpeta) desde el que desea buscar (incluidas las subcarpetas) con el comando cd. En el símbolo del sistema, escriba cd, por ejemplo, cd ~ / Documentos para cambiar el directorio a su carpeta de documentos de inicio. En el símbolo del sistema, escriba el siguiente 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 utiliza una suma de comprobación simple para determinar si los archivos son idénticos. Los nombres de los elementos duplicados se enumerarán en un archivo llamado duplicates.txt en el directorio actual. Abra esto para ver los nombres de archivos idénticos. Ahora hay varias formas de eliminar los duplicados. Para eliminar todos los archivos en el archivo de texto, en el símbolo del sistema, escriba:

while read file; do rm "$file"; done < duplicates.txt
Arrendajo
fuente

Respuestas:

4

En primer lugar, deberá reordenar la primera línea de comando para mantener el orden de los archivos encontrados por el 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 fines de prueba en mi máquina que usé find . -type f -exec cksum {} \;)

En segundo lugar, una forma de imprimir todo menos el primer duplicado es mediante el uso de un archivo auxiliar, digamos /tmp/f2.tmp. Entonces podríamos hacer 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

Solo asegúrese de que /tmp/f2.tmpexista y esté vacío antes de ejecutar esto, por ejemplo a través de los siguientes comandos:

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

Espero que esto ayude =)

Janito Vaqueiro Ferreira Filho
fuente
39

Otra opción es usar fdupes:

brew install fdupes
fdupes -r .

fdupes -r .encuentra archivos duplicados de forma recursiva en el directorio actual. Agregar -dpara eliminar los duplicados: se le preguntará qué archivos guardar; si, en cambio, agrega -dN, fdupes siempre mantendrá el primer archivo y eliminará otros archivos.

Lri
fuente
77
fdupes¡es increíble! ¡Trabajado como un encanto! Gracias hermano.!
racl101
3

Escribí un script que cambia el nombre de sus archivos para que coincida con un hash de sus contenidos.

Utiliza un subconjunto de bytes del archivo para que sea rápido, y si hay una colisión, agrega un contador al nombre como este:

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

Esto facilita la revisión y eliminación de duplicados por su cuenta, sin confiar en el software de otra persona con sus fotos más de lo que necesita.

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

ingrese la descripción de la imagen aquí

SimplGy
fuente
¡+1 solo para la pantalla GIF!
NoobEditor
0

Esto se hace con la ayuda de la aplicación EagleFiler, desarrollada 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

También puede eliminar automáticamente duplicados con el removedor de archivos duplicados sugerido en esta publicación .

Dejise
fuente
1
(1) ¿Qué es "EagleFiler"? ¿Es parte de macOS? Si no, ¿de dónde lo sacas? (2) ¿Se supone que es un bloque de código largo (la forma en que lo arreglé)? (3) Corrija su sangría. (4) Exactamente, ¿cómo se usa esto?
Scott