Титла: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: 4096bits в Oct 02, 2017, 20:05 Почна да не ми стига мястото на лаптопа и външните дискове и вчера си написах това, да ми търси дублиращи се файлове. Може и в bash да се направи с един ред, обаче... Пробвах да го направя да ползва повече ядра и уж да е по-бързо. Не зная, доколко съм направил нещо и ако някой иска, да си каже мнението и да тества. Аз ще го направя, като имам повече време, че терабайти не се проверяват за пет минути. md5 уж е бързо, ма не чак толкова. Днес му добавих само шаренийките и малко коментари.
Python 3.6 Код: #!/usr/bin/env python3 Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: 4096bits в Oct 04, 2017, 10:55 Беше много тъпо, да му кажа смята md5 на всеки файл :D
Преправих го малко, да смята само на тези, дето са с еднакъв размер. Някой може ли да каже, какъв размер парче от файла да му задам да чете с оглед на по-добра производителност? В момента е 1М. За малките файлове може да е добре, но не зная за тези гигабайтовите. Код: #!/usr/bin/env python3 Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: spec1a в Oct 04, 2017, 12:40 Със каква файлова с-ма си ?
Може би по-доброто решение е да ползваш т.нар. "дедупликация" Ако има няколко файла с еднакво съдържание,де факто физически съществува само един, всички останали всъщност са само линкове към "оригиналния". Мисля,нещо подобно има в btrfs Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: 4096bits в Oct 04, 2017, 13:15 В момента на тази система с ext4, имам едно Ubuntu MATE с btrfs, но основно ще се преравят външни носители, които са на ntfs. Мислех си да използвам mmap, но не съм сигурен, дали системата ще си реши сама, колко да качи в паметта, вместо да го задавам ръчно.
Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: remotexx в Oct 04, 2017, 16:22 Колега, реших да те оставя да се побориш малко сам.. и виждам - не съм сгрешил
Ето няколко съвета и от мен 1. Нали се сещаш че и с много (100) нишки няма да стане много по бързо отколкото с 2-4 просто няма как да стане по бързо от скоростта на четене от диска, в сл. Два диска 2. Той този, както и повечето алгоритми са блокови, но ако разглеждаме един блок като неделим то на ниво блок са си поточни, та може да спреш изчисленията при първия блок с разлики т.е. Не знам там тоя клас дето ползваш дали позволява на наколко пъти т.е. След всеки блок да викаш „колко е текущата сума до момента” и ако се различава спираш веднага. Ако класът който ползваш не го позволява виж 3. 3. Ползвай по прост алгоритъм напр. CRC32 който направо си е поточен на ниво int32, можеш да ги разпишеш на ръка дето се вика и да спреш при първата разлика Внимавай само за следното, еднакви суми не гарантират еднакви файлове т.е. Ползвай само за бърза проверка за различни файлове, ако црц32 съвпада пак се налага мд5 А ако очакваш повечето да са еднакви смятай го паралелно с мд5, колкото ако мд5 не позволява изкарване на междинна дума црц32 да ти каже кога да спреш Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: makeme в Oct 04, 2017, 16:59 В Ubuntu Mate има програмче за тази работа :)
Код: sudo fdupes -r /home/ ПС: Даже ще ми е интересно да ги пуснеш да се състезават с твоя скрипт. Може да си направил нещо по-бързо :) Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: 4096bits в Oct 04, 2017, 19:35 Напълно ясно ми е, че всичко зависи от скоростта на трансфер на файловете от дисковете. Нямаше да се блъскам, ако не беше бройката на файлчетата, някои големички. Става въпрос за архиви на години. Музика, снимки, видео и филми, свалени сайтове или части от такива. Тонове pdf документи и книги
Затова се и опитвам да впрегна осемте ядра. Иначе програмки за тази работа има, да. Ако знаех, дали ще се справят по-бързо, нямаше да се занимавам. Неприятната част е, че това не ми е професия и сигурно основни неща не зная. Щом в началото бях почнал да смятам всеки файл, направете си сметката ;D Не се бях сетил, че мога да спра насред сметките на петия или щестия блок например. Ще проверя задължително, как стоят нещата с това. Ако hashlib не го може, ще пробвам с друга библиотека. Искаше ми се да не е такава от трета страна, щото може да трябва да го пренасям. Остава и въпроса с комуникацията между процесите, ако тръгна да правя и това. Ще трябва някак да споделят предишно състояние на чексумите. Redis може би, не зная. Или сокети. Ще стане май мътна и кървава :D ---------------------- Тъй, значи паралелно с размера да следя и crc32 и да добавям файлове в списъка за чексума, само, ако съвпада и размера и crc32? Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: remotexx в Oct 04, 2017, 20:19 ами за малък файл (особено пък ако се очаква повечето да са рaзлични - може и за по-големичък .. напр. 16/32 MB или там колкото ти е буфера на диска) може и само CRC32, като очакването е да не се налага МД5 или айде да кажем очаква се да се наложи МД5 в под 5% от случаите (само когато CRC32 им съвпада)
- но ако файла е голям - напр. 4 ГБ и се очаква да е еднакъв (то там обик. ако размера съвпада вероятността да е същия е много голяма) то тогава ще трябва да се смятат и двете едновременно (за да не се четат 2 х 4 ГБ) т.е. за малки файлове може и поотделно (надяваш се да са различни и да спестиш от несмятане и на МД5) - забавянето е пренебрежимо ако се наложи после и МД5 (данните вече са кеширани - 16/32 Мб - не ги знам колко са големи днешно време дисковите буфери), но за големи (ГБ, ТБ файлове) за да не го четеш по два пъти смятай едновременно, като CRC ще ти каже кога да спреш. CRC-8/16/32/64 е толкова просто че не ти трябва и клас - директно по формулата и ако искаш на всеки 8/16/32/64 бита сравнявай https://en.wikipedia.org/wiki/Cyclic_redundancy_check П.П. би трябвало и МД5 да може да спре - е не на всеки байт, но поне на/след всеки блок и да ти каже колко е сумата до момента, но това само ако ти си го разпишеш, а като те гледам ми се видя готова библиотека да ползваш, а те рядко дават шанс - та само за това предложих CRC32 понеже лесно се смята ...ако библиотеката поддържа показване на междиини МД5 (без да прецаква крайния резултат) тогава карай само с него. П.П.П. Сетих се и друго - Ако стане ноемра само с МД5 тогава внимавай размера на буфера ти т.е. парчето данни което добавяш на всяко четене към МД5 сметалката да е кратно на размера на блока за сътоветното МД4/5/...256, защото ако не е кратна .. е тогава ще си го допълни с нули - добрата новина е че и на двата файла ще го смята еднакво грешно т.е. по този начин сметнати МД5 ще съвпадат, проблема е ако решиш да провериш после на ръка или с друга утилка - да не се чудиш що няма съвпадение... Така като гледам класа който ползваш може и да може да му се извика повече от веднъж да каже колко е сумата до момента, но имай предвид че ще го лови горния БЪГ т.е. ако последния/буфера не е кратен на размера на блока с който работи алгоритъма - ще го допълва (на случайни места с нули - колкото пъти поискаш текущата сума и блока иска допълване) - както вече казах това не е проблем ако на едни и същи локации по двата файла правиш сметките, но няма да съвпадат сумите с истинските (генерирани от нормалните инструменти) Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: remotexx в Oct 04, 2017, 20:43 Не разбрах какво имаш предвид със "въпроса с комуникацията между процесите," - аз мислех че един процес ти е един файл (което пак може да озори диска да чете от много различни места хеле па ако му е и малък ...буфера)
имай предвид, че тези суми не можеш да ги смяташ паралелно (затова са и толкова бавни) - т.е. ако си мислиш да го разпаралелиш (малей каква сложна дума) един файл на 8 части - няма да стане - тези сметалки искат последнователен достъп и напр. втория блок започва с начално състояние сметнато от първия та не може да го разделиш 1 файл на 8 да сметнеш паралелно 8те МД5 - нали накрая ще имаш 8 МД5??? е да ако една е различна значи и файловете са разлчини, но пак ще си ги сметнал и осемте! плюс това понеже нишките се състезават няма гаранция напр. че нишка 1 при файл 1 няма да грабне напр. блок 1,9,... а при файл 2 да грабне 1,10.. (щото позакъсняла малко в сметките) и тогава става мазало, та единствения начин е по една нишка на файл и с динамично управление на броя - напр. 4 БГ файл - само една (иначе ще се омота диска да чете различни големи файлове от различни места), мног малки файлове: повече нишки, но не мнгоо повече отколкото буфера на диска може да събере и за домашно - интересния вариант когато двата диска имат различен размер буфери :-) Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: makeme в Oct 04, 2017, 22:09 Ако си решил да си развиваш знанията - това го разбирам и не чети надолу :)
Ако пък ли искаш решение - програмата, която цитирах я ползвам и пак казвам е добро решение. За да ти дам база за сравнение я пуснах на домашния сървър да ти събера няколко аутпута. Партишъна, който съм сканирал е мой такъв заделен именно за бекъпи. Става въпрос за обикновен евтин хард на 7200 оборота. Цитат големина на файловете: През целия процес процесора почти не е мърдал. Както каза колегата по горе, харда при тези неща е ботълнека и няма смисъл от нишки и тнт (по-голям оувърхед). Не искам да те обезкуражавам по никакъв начин, просто се опитвам да помогна. Успех. ПП: Имаше един лаф: Какво ще правим след това с героите.. Та и при сравнението е така. Ще се чудиш какво да правиш с толкова много еднакви файлове (бил съм там :) ) По горе спомена, че имаш сайтове. Ако са и еднакви ЦиЕМеси там аутпута ще е страшен. Може да помислиш върху пропускане на тези директории. ПП2: При огромни задания, каквото изглежда твоето, оптимизацията на скрипт има лимит. След това следва оптимизиране на процеса, като ръчно (или не) го орязваш според това, което искаш да постигнеш. edit 1: Обещаните изходи от SSD Цитат размер: Тук едното ядро се натовари (~80%) понеже работим с ссд. Както се вижда имаме много повече файлове (както за сканиране, така и като резултат), но по-малко като общ размер и времето е с около 30% по-малко. Като извод може да се каже, че единствено зависиш от броя файлове, а не от тяхната големина. Та както вече казах, помисли върху пропускане на някой директории или ги измести от пътя за сканиране. edit 2: Исках да сравня и скрипта ти (втората версия) с програмата, но като гледам нямам шанс да го подкарам. Инсталирах питон3.6 , но явно има доста други неща. Като за начало срещне ли счупен симлинк и спира, тръгнах да сканирам друга /home папка на друга машина, но зацикли нещо (буквално спря да прави каквото и да е) и когато му набих ctrl+c извади това: Цитат # time python3.6 asd.py /home/ Знам, че го играя малко QA, но понеже с друго не мога, помагам с това :) Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: 4096bits в Oct 04, 2017, 23:35 Понеже програмирането не ми е професия, не ми е отръки все още и както казах, със сигурност ми липсват тухлички някъде надолу, до основите. Та, останал съм с впечатлението, че комуникацията между процеси, не е от най-лесните неща, а това не съм го правил до този момент. Малко сокетчета и това е било. Това във връзка със споделянето на междинната чексума на всеки файл или на crc32.
Това, което се пробвам да направя, е не да разцепя всеки файл на парчета и да смятам тях, а да работя върху няколко файла едновременно. Одеве пусках на по-голяма папка на локалния си диск за проба и видях, че натоварването на процесора направо липсва, та сега ми се мота идеята, вместо да се занимавам да тичам по задника на осем ядра, да пусна всичко да се бачка на едно ядро и да ползвам нещо от рода на asyncio. Това животно тепърва започна да ми се изяснява едва преди половин месец. Още ме е шубе от него, а имам върху какво да го пробвам. По-малки скриптчета, в които ProcessPoolExecutor се справи забележително добре. Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: 4096bits в Oct 05, 2017, 14:38 Така...
Понеже се оказа, че скрипта не работи както трябва - някакви безмислици в output-а - трябваше да го доизчистя. Резултатите от fdupes: real 0m9.005s user 0m1.040s sys 0m3.668s Резултатите от скрипта: real 0m3.786s user 0m3.852s sys 0m1.119s Паралелната обработка на файловете си казва думата. Пуснах го да рови в локалната директория с музика на единия лаптоп дето го пиша на него. Не съм правил промените свързани с предложението за проверка на crc32. Тепърва ще пробвам и това, а след това ще пробвам и на едно ядро, но с async щуротийките. Няма да се учудя, ако този вариант се окаже по-бърз. Скрипта в момента е в този си вид: Код: #!/usr/bin/env python3 Между другото, не зная защо съм вмъкнал и windows-ката команда за чистене на екрана - 'cls' - след като малко по-надолу ползвам 'setterm', кояко съм сигурен я нама в тази система. Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: makeme в Oct 05, 2017, 16:08 Поздравления! Третия вариант работи много добре. Много ми хареса как си украсил аутпута :)
Относно сравнението. На голяма папка е по-бавен: 4096bits_dupes.py: Summarize: Found 48257 foles in /storage/share/. Found 3316 files with 4246 duplicates. Deleting the duplicates will free 7.443 GB. real 6m0.450s fdupes: real 3m45.325s големина: du -sh /storage/share/ 270G /storage/share/ Не знам дали ти остана време да сканираш папка със счупен симлинк, но все още скрипта спира на него. Титла: Re: Прост скрипт за търсене на дублиращи се файлове. Публикувано от: 4096bits в Oct 05, 2017, 21:37 Може евентуално да му се каже, да не следва symlinks. По-рано днес се замислих, дали да не оставя и един файл със пълния път като ключ и чексумите като стойност. В момента е обратното. Може да послужи евентуално за следене, дали има промени по файловете в някоя папка/дял. Може и сегашния да послужи. Относно големите файлове, предполагам, че ще са бави там и то не малко. Чудя се, дали не мога просто да пусна де се сметнат само първия мегабайт или там четири-пет от гигабайтовите файлове. Има някои доста големички, които са компресирани архиви и там не зная, какво ще стане. Може да го оставя да си работи и да ида събота и неделя на планина или нещо такова :D Четох из интернет за разни варианти през няколко мегабайта или десетки мегабайта да се изчислява чексума на няколко стотин К. Ще видя големите точно какво ще ги правя.
Резултатите, кито дадох, нещо не успях да ги получа след това. Има нещо при питона, което не зная съвсем ясно, как се случва. Като се пусне .py файл да се изпълнява, интерпретатора създава .pyc файл и следващия път скрипта се изпълнява по-бързо - от точно този файл. Има вариант да преправя кода със cython-ки синтаксис. Това се компилира после и става наистина бързо. Но първо ще пробвам варианта със asyncio. п.п А може и да се добави проверка, дали обекта е файл |