
У меня 4 жестких диска, и я хочу узнать, какие файлы на этих четырех жестких дисках (включая подкаталоги) являются дубликатами. Это должно быть проверено не только на жестком диске, но и на всех остальных.
Жесткие диски большие (3 ТБ), поэтому они должны быть эффективными (сначала проверяется имя файла, затем контрольная сумма или что-то в этом роде).
решение1
Приведенный ниже скрипт ищет дубликаты файлов в 10 каталогах одновременно, ища дубликаты вкомбинированныйкаталоги.
Он должен быть значительно быстрее, чем оба fdupes
(запуск fdupes -r
) и fslint
; в относительно небольшом каталоге размером 40 ГБ, сохраненном локально, скрипту потребовалось 5 секунд, чтобы создать список дубликатов, в то время как для fdupes
более fslint
крупного каталога (700 ГБ, ~350000 файлов) на относительно медленном внешнем USB-накопителе потребовалось 90 минут. С fdupes это заняло бы более 200-250 минут, если смотреть на индикацию прогресса (что хорошо, скрипт ниже не показывает прогресс), но я не ждал его до конца.
Я должен упомянуть, что, например, fslint
предлагает дополнительную функциональность, которой скрипт не предоставляет (как таковой), поэтому сравнение проводится строго по созданию списка дубликатов.
Кроме того, скорость отчасти зависит от того, насколько быстро считывается диск: я протестировал несколько носителей (в том числе на сетевом диске) с большими различиями, особенно в небольших каталогах, где создание списка файлов занимает относительно большую часть работы (времени).
Суть в том, что это не будет быстрой работой в любом случае, вы можете спросить себя, не слишком ли велики каталоги.
Как это работает
Когда скрипт находит дубликаты, они выводятся в следующем виде:
Creating file list... /home/jacob/Bureaublad/test2
Creating file list... /home/jacob/Bureaublad/foto
Creating file list... /home/jacob/Bureaublad/Askubuntu
Checking for duplicates (10790 files)...
------------------------------------------------------------
> found duplicate: test1.txt 2
/home/jacob/Bureaublad/test2/test1.txt
/home/jacob/Bureaublad/test2/another directory/test1.txt
------------------------------------------------------------
и так далее
Сценарий
#!/usr/bin/env python3
import os
import sys
total_filelist = []
total_names = []
def find_files(directory):
l = []; l2 = []
for root, dirs, files in os.walk(directory):
for file in files:
l.append(file)
l2.append(root+"/"+file)
return (l, l2)
i = 1
while i <= 10:
try:
dr = (sys.argv[i])
print("Creating file list...", dr)
total_filelist = total_filelist+find_files(dr)[1]
total_names = total_names+find_files(dr)[0]
i = i+1
except IndexError:
break
print("Checking for duplicates ("+str(len(total_names)),"files)...")
for name in set(total_names):
n = total_names.count(name)
if n > 1:
print("-"*60,"\n> found duplicate:",
name, n, "\n")
for item in total_filelist:
if item.endswith("/"+name):
print(item)
print("-"*60, "\n")
Скопируйте его в пустой файл, сохраните как find_dupes.py
и запустите командой:
python3 <script> <directory1> <directory2> <directory3>
До макс. 10 каталогов
Дополнительные параметры сценария
Относительно просто добавить дополнительные функции; например, переместить дубликаты в другой каталог, переименовать и т. д., чтобы можно было вручную или автоматически решить, какой файл сохранить.
Как сделать работу выполнимой
Ваши каталоги кажутся огромными. Чтобы сделать работу разумно возможной, есть другой, более сложный способ предотвратить "захлебывание" системы: вместо того, чтобы выполнять работу над всеми типами файлов (расширениями) сразу, вы можете разбить работу на частиразделы по типу файлаНебольшой тест на каталоге из 30 000 файлов сократил время примерно с 20 секунд (все файлы) до 0,3 секунды для одного расширения.
Чтобы скрипт искал дубликаты только одного типа файлов, замените раздел скрипта:
def find_files(directory):
l = []; l2 = []
for root, dirs, files in os.walk(directory):
for file in files:
l.append(file)
l2.append(root+"/"+file)
return (l, l2)
к:
def find_files(directory):
l = []; l2 = []
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith(".py"): # example .py extension
l.append(file)
l2.append(root+"/"+file)
return (l, l2)
Поиск встречающихся расширений файлов
Чтобы вывести список всех встречающихся расширений файлов в каталоге, можно использовать следующий скрипт:
#!/usr/bin/env python3
import sys
import os
l = []
for root, dirs, files in os.walk(sys.argv[1]):
for f in files:
if (
f.startswith("."),
f.count(".") == 0,
f.endswith("~"),
) == (False, False, False):
l.append(f[f.rfind("."):])
for item in set(l):
print(item)
Скопируйте его в пустой файл, сохраните как find_extensions.py
и запустите командой:
python3 <script> <diretory>
Пример вывода:
.txt
.mp3
.odt
.py
.desktop
.sh
.ods
решение2
Если вы хотите использовать действительно мощный графический интерфейс, попробуйте FSlint из Центра программного обеспечения.
(Я вижу, что @lemonsqueeze предложил это в комментариях выше).
Вот ответ, описывающий использование FSlint: https://askubuntu.com/a/472244/100356
решение3
Я использовал проект FSlint и нашел способ сделать это.
Мой процесс, чтобы все это упорядочить на нескольких дисках с требованием запускать все через CLI и экран
sudo apt-get install fslint
find path1/2/3 -type f -empty -delete
&find path1/2/3 -type d -empty -delete
(чтобы избавиться от всего пустого или не полностью скопированного)/usr/share/fslint/fslint/findsn path1 path2 path3
(удалить все, что хранится в одном каталоге с одинаковым размером на разных дисках)/usr/share/fslint/fslint/findup path1 path2 path3
(удалить все дубликаты файлов)find path1/2/3 -type d -empty -delete
(чтобы избавиться от каталогов, которые пусты после findup)
После этого я смог mhddfs
снова смонтировать все диски как объединенный диск без дубликатов, которые снова тратили дисковое пространство.