Como han señalado otros, podría haber problemas aquí con la secuencia de comandos de la shell dependiendo de cómo se hicieron los duplicados. Teóricamente podrías evitarlos copiando la carpeta y probando primero, pero la única manera de verificar totalmente es si los revisas a mano, lo que en cierto modo desvirtúa el propósito.
Este es un archivo de Python que uso para una deduplicación similar que pueda tener. Escanea la carpeta en busca de archivos usando su sha256, retiene el nombre de archivo más alto alfabéticamente (que generalmente debería mantener los nombres de archivo más limpios) y elimina los demás. Puedes cambiar la variable dry_run de la antepenúltima línea a true así:
if __name__ == '__main__':
d = Deduplicator(path, dry_run=True)
d.deduplicate()
Para verificar que los archivos que quieres borrar son los que realmente se van a eliminar. Y, por supuesto, cambie la línea 4 de /ruta/a/sus/archivos por el directorio real donde están los archivos.
Para ejecutar, en un mac debería ser simplemente capaz de ejecutar:
python /path/to/your/deduplicate.py
Donde /ruta/para/tu/script es donde guardas este archivo .py. Básicamente, ponga lo siguiente en un archivo de texto y nómbrelo deduplicate.py:
import os
import hashlib
path = '/path/to/your/files'
class Deduplicator:
def __init__(self, path, dry_run=True):
self.path = path
self.file_dict = dict()
self.dry_run = dry_run
def deduplicate(self):
self.get_files()
self.clean_files()
def get_file_hash(self, file_path):
with open(file_path, 'rb') as f:
file = f.read()
hash = hashlib.sha256(file).hexdigest()
return hash
def get_files(self):
# Loop through the directory
for file in os.listdir(path):
# Get the file hash
hash = self.get_file_hash(os.path.join(self.path, file))
# If we haven't seen the hash yet, go ahead and initiate the list
if not self.file_dict.get(hash):
self.file_dict[hash] = list()
# Then add this filename to that hashed value
self.file_dict[hash].append(file)
def clean_files(self):
for hash, file_names in self.file_dict.items():
file_names.sort(reverse=True)
files_to_delete = file_names[:-1]
print(f"File to keep: {file_names[0]}")
print(f'Files to delete: {files_to_delete}')
print('-'*50)
if not self.dry_run:
for file in files_to_delete:
full_path = os.path.join(path,file)
print(f"...deleting: {full_path}")
os.remove(full_path)
if __name__ == '__main__':
d = Deduplicator(path, dry_run=False)
d.deduplicate()