Sergey Stremidlo wrote: > 05.11.2011 08:13, Нагашибай Жанибек пишет: >> Какие программы есть на эту тему? Желательно, чтоб можно было >> посмотреть список файлов-дубляжей и выборочно удалить любой из них. >> >> > Вот моё творение:
Помимо того, что велосипед (fdupes!), несколько замечаний ниже: > #! /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 exec 2>$0.errlog > > if [ -e $0.process ] > then > echo "Already running..." Я бы не помещал флаг в той же директории, что и скрипт. И сделал бы его per-user. > exit > fi > > if [ $# -ne 2 ] > then > echo "Use: $0 <dir> <out_file>" > exit exit 1 > fi > > FINDDIR="$1" > TMPNAME=`tempfile` > > echo 'Построение списка файлов...' > $0.process > > # составим список только файлов (исключая директории) > > find $FINDDIR -type f > $TMPNAME.list 1) "$FINDDIR" 2) использовать $TMPNAME.list и иже с ним - небезопасно. TMPLIST=`tempfile` TMPLIST2=`tempfile` MD5LIST=`tempfile` MD5SORT=`tempfile` DUPS=`tempfile` trap "rm -f $TMPLIST $TMPLIST2 $MD5LIST $MD5SORT $DUPS; exit" 0 INT TERM QUIT find ... >$TMPLIST > # отфильтруем не нужные > > cat $TMPNAME.list | grep -v "/Trash/" > $TMPNAME.list2 1) useless use of cat: grep -v "/Trash/" $TMPLIST ... > $TMPLIST2 2) можно было бы запихнуть это в условие сразу в find - find "$FINDDIR" -name Trash -prune -o -type f -print > mv $TMPNAME.list2 $TMPNAME.list > > # определим количество файлов > # для того чтобы отображать сколько файлов уже обработано > > CNT=`grep -c "" $TMPNAME.list` s/grep -c ""/wc -l/ > # вычислим суммы файлов > rm -f $TMPNAME.md5 > n=1 > while read FN > do > echo "$n of $CNT" > $0.process > MD5=`md5sum "$FN"` I'd prefer higher efficiency over UI frills. tr '\n' '\0' < $TMPLIST | xargs -0r md5sum >$MD5LIST > 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#* } while read MD5 FN ... > if [ "$MD5" = "$MD5PRE" ] > then > # если мд5 текущего и предыдущего совпали > # но имя предыдущего файла не пустое, значит > выводим две строки > # и опустошаем имя предыдущего файла чтобы по > этому признаку определить > # что нужно выводить одну строку а не две > if [ "$FNPRE" != "" ] if [ -n "$FNPRE" ] > then ... но я бы для поиска дупликатов заюзал uniq -w32 -D :-) > 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" Ах да, коллизии для md5 не новость, давно пора переходить с md5 на более другой хеш; учитывая, что sha1 уже тоже дисквалифицирован, можно сразу на sha256 (или sha512). -- To UNSUBSCRIBE, email to debian-russian-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/j93qgu$49v$1...@dough.gmane.org