Поиск дубликатов
Это небольшое приложение написанное на Perl'е. Оно позволяет сравнить два каталога (рекурсивно), обнаружить и при необходимости удалить из второго каталога дубликаты файлов из первого. Сравнение проводится вычислением md5 сумм.
Написал я эту программу более года назад и считаю, что достаточно обкатал его. Работа проверялась под WinXP и Debian GNU/Linux.
Скачать
Инсталляция
Просто распакуйте в любое удобное для Вас место.
Если у вас юниксоподобная система и perl установлен (а он по умолчанию установлен практически везде), то запуск обычный
./finddupe
Если Вы несчастный обладатель windows придётся потрудится. Скачиваем дистрибутив и устанавливаем perl. Это может быть ActivePerl. Я сам не пробовал, поскольку под виндой у меня всегда перл ставился вместе с Apache.
Для конкретности переименуйте finddupe в finddupe.pl. И если в переменной path прописаны пути к перлу, то можно запустить из консоли:
perl finddupe.pl
Использование
Ключики которые программа понимает она сама Вам покажет будучи запущена без параметров или с параметром -h.
Небольшой пример использования:
finddupe -d -i first/ -o second/
Программа просмотрит каталоги first и second и удалит из second все файлы которые есть в first
Исходный код
Последняя версия v0.2.1
#!/usr/bin/perl -w # # Finddupe v0.2.1 use for search and delete duplicate files # Copyright (C) 2005-2006 Ivan A. Alferov <ivan@iar.spb.ru> # # web: http://iar.spb.ru/projects/finddupe # # original name: finddupe use Digest::MD5; use Getopt::Std; getopts('hlvspdi:o:', \%args); if ($args{l}) { print <<EOF; License: Finddupe v0.2 use for search and delete duplicate files Copyright (C) 2005-2006 Ivan A. Alferov <ivan\@iar.spb.ru> http://iar.spb.ru This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA EOF exit; } if ($args{h} || !($args{i} && $args{o})) { print <<EOF; Finddupe v0.2.1 use for search and delete duplicate files Copyright (C) 2005-2006 Ivan A. Alferov <ivan\@iar.spb.ru> http://iar.spb.ru Usage: finddupe [-h] [-i inpath -o outpath] -h -- this help -l -- license -v -- more verbose -s -- slience -d -- delete duplicates -p -- delete empty dir on destination directory -i inpath -- source directory path -o outpath -- destination directory path (hereof remove) Platform supported: linux, WinXP, maybe platform independent. EOF exit; } $srcpath = $args{i}; $dstpath = $args{o}; $regexp = 0; %LIST1 = (); print "Analizing $srcpath...\n"; lsr($srcpath, \%LIST1); print "Compare $srcpath and $dstpath...\n"; rrem($dstpath, \%LIST1); print "Done.\n"; ### sub rrem ($directory, \%hash) # Удаляет файлы совпадающие sub rrem { my $dir = shift; $dir .= '/' unless ($dir =~ m{[\\/]$}); my $lst = shift; my $name; my $D; opendir $D, $dir; my $cnt = 0; while ($name = readdir $D) { if ($name !~ /^\./) { my $fullname = $dir.$name; unless (eval($regexp)) { if (-d $fullname) { $cnt += &rrem($fullname, $lst); } else { my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($fullname); print "Check: $name: $size\n" if ($args{v}); if (($source = $$lst{"$name/$size"}) && ($$lst{"$name/$size"} ne $fullname)) { my $ctx = Digest::MD5->new; open (*FILE, $source); $ctx->addfile(*FILE); close (*FILE); my $md5_1 = $ctx->hexdigest; $ctx = Digest::MD5->new; open (*FILE, $fullname); $ctx->addfile(*FILE); close (*FILE); my $md5_2 = $ctx->hexdigest; if ($md5_1 eq $md5_2) { if( $args{d} ) { unlink $fullname; print "Remove: $fullname\n" unless ($args{'s'}); } else { print "Duplicate: $fullname\n" unless ($args{'s'}); } } else { $cnt++; } } else { $cnt++; } } } } } closedir $D; if ((!$cnt) && ($args{p})) { if (rmdir $dir) { print "Remove directory: $dir\n" unless ($args{'s'}); } else { print "Can't remove directory: $dir\n" unless ($args{'s'}); } } return $cnt; } ### sub lsr ($directory, \%hash) # Возвращает рекурсивный список файлов начиная с директории sub lsr { my $dir = shift; $dir .= '/' unless ($dir =~ m{[\\/]$}); my $lst = shift; my $D; my $name; opendir $D, $dir; while ($name = readdir $D) { if ($name !~ /^\./) { my $fullname = $dir.$name; unless (eval($regexp)) { if (-d $fullname) { &lsr($fullname, $lst); } else { my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($fullname); print "Analize: $name: $size\n" if ($args{v}); $$lst{"$name/$size"} = $fullname; } } } } closedir $D; }







Дискуссия
Мой пост на другом сайте: Очень нужно видеть папки-дубликаты, желательно в двух панелях (аля Norton Commander). Синхронное хождение по папкам - зашел в другую папку в текущей панели и автоматом в противоположной. Подсветка для почти одинаковых папок (несколько файлов разные/отсутствуют и т.д.). И еще не помешает фильтр на даты (изменения, создания), атрибуты и т.д., включая разные NTFS-примочки (потоки, коментарии и т.д.). Пожалуйста, посоветуйте, кто знает, где это есть (pk_income a*t mail.ru).
Пожелания к данному продукту на перле. Сравнение по md5 - только предварительное (результат - кандидаты на на полное, побайтное сравнение). И само полное сравнение.
- **полужирный**
- //курсив//
- > цитата
- [[http://link | Заголовок ссылки]]
Больше о синтаксисе...