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"
|