05.11.2011 08:13, Нагашибай Жанибек пишет:
Какие программы есть на эту тему? Желательно, чтоб можно было посмотреть список файлов-дубляжей и выборочно удалить любой из них.
Вот моё творение: #! /bin/bash # Алгоритм работы скрипта: # 1. Составить список файлов # 2. Вычислить все md5 суммы файлов # 3. Отсортировать список по md5 суммам # 4. Пройтись по списку, сравнивая попарно md5 записанные в строках и # если текущая совпала с предыдущей то вывести обе, но одну пометить file: а другую dup: # А чтобы третья и последующая так же не выдавали метки file: то можно использовать имя файла в предыдущей строке # как флаг, и обнулять его после первого вывода метки file: # # впоследствии можно скормить файл grep "^dup" и затем rm # # Создаем файл блокировки find_duplicate.process чтобы повторно не запустился поиск # одновременно в этом файле находится фраза, описывающая какие действия выполняет скрипт. # Вот примеры того что бывает в этом файле: # 'Построение списка файлов...' # '23634 of 3974653' # # fixme: перенаправить stderr в файл # такая команда не помогает: # 2>$0.errlog if [ -e $0.process ] then echo "Already running..." exit fi if [ $# -ne 2 ] then echo "Use: $0 <dir> <out_file>" exit fi FINDDIR="$1" TMPNAME=`tempfile` echo 'Построение списка файлов...' > $0.process # составим список только файлов (исключая директории) find $FINDDIR -type f > $TMPNAME.list # отфильтруем не нужные cat $TMPNAME.list | grep -v "/Trash/" > $TMPNAME.list2 mv $TMPNAME.list2 $TMPNAME.list # определим количество файлов # для того чтобы отображать сколько файлов уже обработано CNT=`grep -c "" $TMPNAME.list` # вычислим суммы файлов rm -f $TMPNAME.md5 n=1 while read FN do echo "$n of $CNT" > $0.process MD5=`md5sum "$FN"` echo "$MD5" >> $TMPNAME.md5 let n=n+1 done < $TMPNAME.list rm $0.process rm $TMPNAME.list MD5PRE= FNPRE= rm -f $TMPNAME.dup n=1 sort $TMPNAME.md5 > $TMPNAME.md5.sorted rm -f $TMPNAME.md5 while read LINE do MD5=${LINE%% *} FN=${LINE#* } if [ "$MD5" = "$MD5PRE" ] then # если мд5 текущего и предыдущего совпали # но имя предыдущего файла не пустое, значит выводим две строки # и опустошаем имя предыдущего файла чтобы по этому признаку определить # что нужно выводить одну строку а не две if [ "$FNPRE" != "" ] then echo "file: $FNPRE" >> $TMPNAME.dup echo " dup: $FN" >> $TMPNAME.dup FNPRE= else echo " dup: $FN" >> $TMPNAME.dup fi let n=n+1 else MD5PRE=$MD5 FNPRE=$FN fi done < $TMPNAME.md5.sorted rm -f $TMPNAME.md5.sorted mv $TMPNAME.dup "$2"