Дошло до этого.После незначительного тестирования это, кажется, работает, хотя требуется больше.Опять же, это может быть очень долго, в зависимости как от количества файлов, так и от их размера:
import filecmp
import os
from collections import defaultdict
from sys import argv
def compareDirs(d1,d2):
files1 = defaultdict(set)
files2 = defaultdict(set)
subd1 = set()
subd2 = set()
for entry in os.scandir(d1):
if entry.is_dir(): subd1.add(entry)
else: files1[os.path.getsize(entry)].add(entry)
#Collecting first to compare length since we are guessing no
#match is more likely. Can compare files directly if this is
# not true.
for entry in os.scandir(d2):
if entry.is_dir(): subd2.add(entry)
else: files2[os.path.getsize(entry)].add(entry)
#Structure not the same. Checking prior to content.
if len(subd1) != len(subd2) or len(files1) != len(files2): return False
for size in files2:
for entry in files2[size]:
for fname in files1[size]: #If size does not exist will go to else
if filecmp.cmp(fname,entry,shallow=False): break
else: return False
files1[size].remove(fname)
if not files1[size]: del files1[size]
#Missed a file
if files1: return False
#This is enough since we checked lengths - if all sd2 are matched, sd1
#will be accounted for.
for sd1 in subd1:
for sd2 in subd2:
if compareDirs(sd1,sd2): break
else: return False #Did not find a sub-directory
subd2.remove(sd2)
return True
print(compareDirs(argv[1],argv[2]))
Рекурсивно вводите оба каталога.Сравнить файлы на первом уровне - не удастся, если нет совпадений.Затем попробуйте сопоставить любой вложенный каталог в первом каталоге с любым вложенным каталогом в следующем, пока все не будут сопоставлены.
Это наиболее наивное решение.Возможно, обход среднего дерева и только соответствующие размеры и структура были бы полезны в среднем случае.В этом случае функция будет выглядеть аналогично, за исключением того, что мы сравним getsize
вместо использования filecmp
и сохраним соответствующие древовидные структуры, поэтому второй запуск будет быстрее.
Конечно, в случаенесколько подкаталогов с точно такими же структурами и размерами, нам все равно нужно сравнить все возможности сопоставления.