Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Usuwanie duplikatów

16 views
Skip to first unread message

grryf

unread,
Oct 7, 2009, 9:09:19 AM10/7/09
to
Proszę dodajcie swoje 3 grosze:

# CEL: USUN POPRZEDNIE WERSJE:
# Algorytm:
# 1. skataloguj wszystkie pliki w podkatalogach, zapisz [nazwa,
sciezka, rozmiar, modyfikacja]
# 2. Posortuj wg nazwy i rozmiaru
# 3. Sprawdz kolejne pliki, jezeli nazwa i rozmiar sa takie same jak
nastepnego pliku to usun ktorys

# Czas ostatniej modyfikacji #os.stat(path).st_mtime

# Znane bledy: program trzeba wykonac 2-3 razy bo za kazdym razem
jeszcze cos znajduje (duzo duplikatow jeden za drugim)

import os
pliki = []


# 1:
sciezka = r"d:\My Documents\Downloads\Music_mp3"

def find_dupl(sciezka):
from os.path import join
for root, dirs, files in os.walk(sciezka):
for name in files:
pliki.append([name, root+'\\'+name, os.stat(root+'\
\'+name).st_size, os.stat(root+'\\'+name).st_mtime])
print "Skatalogowano plikow:", len(pliki)

find_dupl(sciezka)


# 2:
# Wlasna funkcja sortujaca ktora sortuje po dwoch parametrach
def multisort(x,y):
nazwa = 0
sciezka = 1
rozmiar = 2
data_modyf = 3
if x[nazwa] > y[nazwa]:
return 1
elif x[nazwa] < y[nazwa]:
return -1
else:
if x[rozmiar] > y[rozmiar]:
return 1
elif x[rozmiar] < y[rozmiar]:
return -1
else:
return 0

# Sortowanie przy uzyciu wlasnej funkcji sortujacej
pliki.sort(multisort)


# 3:
def usun_dupl(pliki):
nazwa = 0
sciezka = 1
rozmiar = 2
data_modyf = 3
poprzedni = pliki[0]
ile = 0
for plik in pliki[1:]:
if poprzedni == None:
poprzedni = plik
continue
if plik[nazwa] == poprzedni[nazwa] and plik[rozmiar] ==
poprzedni[rozmiar]:
if plik[data_modyf] > poprzedni[data_modyf]:
os.remove(poprzedni[sciezka])
ile+=1
elif plik[data_modyf] < poprzedni[data_modyf]:
os.remove(plik[sciezka])
ile+=1
plik = None
else:
os.remove(poprzedni[sciezka])
ile+=1
poprzedni = plik
print "Usunieto plikow:",ile

usun_dupl(pliki)

Bart Ogryczak

unread,
Oct 7, 2009, 10:02:46 AM10/7/09
to
On Oct 7, 3:09 pm, grryf <rade...@gmail.com> wrote:
> Proszę dodajcie swoje 3 grosze:
>
> # CEL: USUN POPRZEDNIE WERSJE:
> # Algorytm:
> # 1. skataloguj wszystkie pliki w podkatalogach, zapisz [nazwa,
> sciezka, rozmiar, modyfikacja]
> # 2. Posortuj wg nazwy i rozmiaru
> # 3. Sprawdz kolejne pliki, jezeli nazwa i rozmiar sa takie same jak
> nastepnego pliku to usun ktorys
>
> # Czas ostatniej modyfikacji #os.stat(path).st_mtime
>
> # Znane bledy: program trzeba wykonac 2-3 razy bo za kazdym razem
> jeszcze cos znajduje (duzo duplikatow jeden za drugim)
>
> import os
> pliki = []
>
> # 1:
> sciezka = r"d:\My Documents\Downloads\Music_mp3"
>
> def find_dupl(sciezka):
>     from os.path import join
>     for root, dirs, files in os.walk(sciezka):
>         for name in files:
>             pliki.append([name, root+'\\'+name, os.stat(root+'\
> \'+name).st_size, os.stat(root+'\\'+name).st_mtime])
>     print "Skatalogowano plikow:", len(pliki)


def find_dupl(sciezka) #nieco nie pasuje nazwa


for root, dirs, files in os.walk(sciezka):

pliki.extend([(name, join(root,name), os.stat( join
(root,name)).st_size,os.stat(join(root,name)).st_mtime) for name in
files])

I tak nie tędy droga... ale o tym zaraz...

> # 2:
> # Wlasna funkcja sortujaca ktora sortuje po dwoch parametrach
> def multisort(x,y):

Nie ma potrzeby, zwykłe sortowanie robi to automatycznie.
pliki.sort()

łał...

Ok, a tak od zera:


from os.path import join

def slownik_duplikatow(sciezka):
duplikaty = {}


for root, dirs, files in os.walk(sciezka):
for name in files:

stat = os.stat(join(root,name))
duplikaty.setdefault((name, stat.st_size),[]).append
((stat.st_mtime, root))

# jaśniej...
def usun_duplikaty(slownik):
for (name,size), lista in slownik.items():
if len(lista)>1:
lista.sort(reverse=true) # posortowane od najnowszego
duplikaty_do_skasowania = lista[1:] #wszystkie z wyjątkiem
najnowszego
for mtime, root in duplikaty_do_skasowania:
os.remove(join(root,name))

# ... albo krócej

def usun_duplikaty(slownik):
for (name,size), lista in slownik.items():
for mtime, root in sorted(lista,reverse=true)[1:]:
os.remove(join(root,name))


grryf

unread,
Oct 9, 2009, 4:40:05 AM10/9/09
to
Bardzo mi się podoba Twoje rozwiązanie! Dziękuję za uwagę.

A poniżej ten sam kod (by Bart), w pełni działający:

from os.path import join
import os

duplikaty = {}
sciezka = r"d:\My Documents\Downloads\Programs"

def slownik_duplikatow(sciezka):
#duplikaty = {}


for root, dirs, files in os.walk(sciezka):
for name in files:
stat = os.stat(join(root,name))
duplikaty.setdefault((name, stat.st_size),[]).append
((stat.st_mtime, root))

slownik_duplikatow(sciezka)

# ... albo krócej
def usun_duplikaty(slownik):
for (name,size), lista in slownik.items():

for mtime, root in sorted(lista,reverse=True)[1:]:
os.remove(join(root,name))

usun_duplikaty(duplikaty)

#Ps. co do sort'a w moim programie to aby sortowal po dwoch
argumentach to naprawde bylo trzeba napisac multisort (sprawdzalem)

Bart Ogryczak

unread,
Oct 9, 2009, 8:35:58 AM10/9/09
to
On Oct 9, 10:40 am, grryf <rade...@gmail.com> wrote:

> #Ps. co do sort'a w moim programie to aby sortowal po dwoch
> argumentach to naprawde bylo trzeba napisac multisort (sprawdzalem)

Zapewne wystarczyło zmienić kolejność, tak żeby te dwa pola po których
sortowałeś były na początku (tak jak miałeś, sortowałeś po polu
pierwszym i trzecim).


0 new messages