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"


Ответить