[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Поиск и удаление дублирующих файлов



В Sat, 5 Nov 2011 10:13:36 +0600
Нагашибай Жанибек <njm.janik@yandex.ru> пишет:

> Какие программы есть на эту тему? Желательно, чтоб можно было
> посмотреть список файлов-дубляжей и выборочно удалить любой из них.
> 
> 

Моё творение:

#! /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"


Reply to: