Удаление дубликатов файлов с помощью Python

Python Программирование и разработка

В этой статье мы собираемся использовать концепцию, называемую хешированием, для идентификации уникальных файлов и удаления повторяющихся файлов с помощью Python.

Требуемые модули:

  • tkinter: нам нужно дать нам возможность выбрать папку, в которой мы хотим выполнить этот процесс очистки, поэтому каждый раз, когда мы запускаем код, мы должны получать диалоговое окно файла для выбора папки, и мы собираемся использовать библиотеку Tkinter. В этой библиотеке у нас есть метод «askdirectory», который можно использовать, чтобы попросить пользователя выбрать каталог. Чтобы установить эту библиотеку, введите следующую команду в IDE/терминале.
pip install tk
  • hashlib: чтобы использовать хеш-функцию md5, нам нужна библиотека hashlib. Чтобы установить эту библиотеку, введите следующую команду в IDE/терминале.
pip install hashlib
  • os: этот модуль помогает нам удалять дубликаты файлов, предоставляя функции для извлечения содержимого файлов, удаления файлов и т. д. Чтобы установить эту библиотеку, введите следующую команду в IDE/терминал. Модуль os является частью стандартной библиотеки Python.

Подход:

  • Мы попросим пользователя выбрать папку, и мы будем искать в этом зонтичном каталоге все повторяющиеся и избыточные файлы.
  • Мы возьмем содержимое каждого файла и пропустим его через хеш-функцию, которая сгенерирует уникальную строку, соответствующую уникальному файлу.
  • Хэш-строка будет иметь фиксированный размер, и размер будет зависеть от типа используемой хэш-функции. У нас есть много хеш-функций, таких как md5, SHA1 или SHA 256 и многие другие. В этой статье мы будем использовать хэш md5, и он всегда будет создавать хэш-значение длиной 32 символа, независимо от размера файла и типа файла.
  • Чтобы обнаружить дубликаты файлов, а затем удалить эти файлы, мы будем поддерживать словарь Python.
  • Мы собираемся передать хеш-строку каждого файла внутри каждой подпапки корневого каталога в качестве ключей словаря и путей к файлам в качестве значений словаря.
  • Каждый раз при вставке новой файловой записи мы будем проверять, не появляются ли в нашем словаре повторяющиеся записи. Если мы найдем какой-либо дубликат файла, мы возьмем путь к файлу и удалим этот файл.
Читайте также:  Учебное пособие по Python: начало работы с Jupyter Notebook

Поэтапная реализация

Шаг 1: Импортируйте библиотеки Tkinter, os, hashlib и pathlib.

Python 3

from tkinter.filedialog import askdirectory
from tkinter import Tk
import os
import hashlib
from pathlib import Path

Шаг 2: Мы используем tk.withdraw, потому что мы не хотим, чтобы окно графического интерфейса tkinter появлялось на нашем экране, нам нужен только диалог файла для выбора папки. askdirectory(title=»Select a folder») эта строка кода открывает диалоговое окно на экране, через которое мы можем выбрать папку.

Python 3

Tk().withdraw()
file_path = askdirectory(title="Select a folder")

Шаг 3: Далее нам нужно перечислить все файлы в нашей корневой папке. Для этого нам нужен модуль ОС, os.walk() принимает путь к нашей корневой папке в качестве аргумента, проходит через каждый подкаталог данной ему папки и выводит список всех файлов. Эта функция возвращает список кортежей с тремя элементами. Первый элемент — это путь к этой папке, второй элемент — все подпапки внутри этой папки, а третий элемент — список всех файлов внутри этой папки.

Python 3

list_of_files = os.walk(file_path)

Шаг 4: Наша конечная цель — перечислить все файлы в каждом подкаталоге и в главном каталоге, поэтому мы запускаем цикл for для всех файлов. Нам нужно открыть каждый файл и преобразовать его в хеш-строку, для этого мы определим переменную с именем hash_file. Хэш-функция md5 преобразует все содержимое нашего файла в хэш md5. Чтобы открыть файл, нам нужно сначала указать путь к нему, поэтому здесь мы используем другую функцию в модуле os, которая называется os.path.join(). Итак, мы скажем открыть файл, используя путь к файлу в режиме чтения. Это преобразует наш файл в хэш md5. Чтобы получить хеш-строку, мы будем использовать метод hexdigest().

Python 3

for root, folders, files in list_of_files:
    for file in files:
        file_path = Path(os.path.join(root, file))
        Hash_file = hashlib.md5(open(
          file_path,'rb').read()).hexdigest()

Шаг 5: Чтобы обнаружить дубликаты файлов, мы собираемся определить пустой словарь. Мы добавим элементы в этот словарь, и ключом каждого элемента будет хэш файла, а значением будет путь к файлу. Если хэш файла уже был добавлен в этот уникальный словарь файлов, это означает, что мы нашли дубликат файла, и нам нужно удалить этот файл, поэтому мы просто удалим этот файл с помощью функции os.remove(). Если его там нет, мы добавим его в этот словарь.

Читайте также:  Vim или Emacs

Python3

unique_files = dict()
if Hash_file not in unique_files:
    unique_files[Hash_file] = file_path
else:
    os.remove(file_path)
    print(f"{file_path} has been deleted")

Ниже приведена полная реализация:

Python3

from tkinter.filedialog import askdirectory
 
# Importing required libraries.
from tkinter import Tk
import os
import hashlib
from pathlib import Path
 
# We don't want the GUI window of
# tkinter to be appearing on our screen
Tk().withdraw()
 
# Dialog box for selecting a folder.
file_path = askdirectory(title="Select a folder")
 
# Listing out all the files
# inside our root folder.
list_of_files = os.walk(file_path)
 
# In order to detect the duplicate
# files we are going to define an empty dictionary.
unique_files = dict()
 
for root, folders, files in list_of_files:
 
    # Running a for loop on all the files
    for file in files:
 
        # Finding complete file path
        file_path = Path(os.path.join(root, file))
 
        # Converting all the content of
        # our file into md5 hash.
        Hash_file = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
 
        # If file hash has already #
        # been added we'll simply delete that file
        if Hash_file not in unique_files:
            unique_files[Hash_file] = file_path
        else:
            os.remove(file_path)
            print(f"{file_path} has been deleted")
Оцените статью
bestprogrammer.ru
Добавить комментарий