Re: Поиск и удаление дублирующих файлов
19.11.11 15:07, Michael Shigorin написав(ла): On Sun, Nov 06, 2011 at 08:31:09PM +0600, Andrey Rahmatullin wrote: Какие программы есть на эту тему? Желательно, чтоб можно было посмотреть список файлов-дубляжей и выборочно удалить любой из них. Несколько не в тему. Вместо удаления повторов, я обычно заменяю их одним файлом с несколькими именами (e. g., через ln(1)) предварительно проверив совпадение mtime и содержимого. (И, конечно, то, что это /различные/ файлы.) apt-get install hardlink JFYI, ldv@ некоторое время тому рекомендовал вместо него hardlinkpy.. В дебиане будто не наблюдаю -- http://hardlinkpy.googlecode.com/ Пользовался fdupes. Потом переписал на Python (дополнив и ускорив). #!/bin/env python # FDUPES Copyright (c) 1999-2002 Adrian Lopez # # Permission is hereby granted, free of charge, to any person # obtaining a copy of self software and associated documentation files # (the "Software"), to deal in the Software without restriction, # including without limitation the rights to use, copy, modify, merge, # publish, distribute, sublicense, and/or sell copies of the Software, # and to permit persons to whom the Software is furnished to do so, # subject to the following conditions: # # The above copyright notice and self permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. __version__ = '1.50-PR2-s1' import sys, os, stat, optparse, time try: from hashlib import md5 except ImportError: from md5 import md5 CHUNK_SIZE = 8192 PARTIAL_MD5_SIZES = [4096, 16384, 65536, 262144, 1048576] class filestat: def __init__( self, path ): self.filename = path self.stat = os.stat( path ) self.signatures = [None] * len( PARTIAL_MD5_SIZES ) self.duplicates = None def getcrcpartial( self, i ): if self.signatures[i] is None: f = open( self.filename, 'rb' ) self.signatures[i] = md5( f.read( PARTIAL_MD5_SIZES[i] ) ).digest() f.close() if self.stat.st_size <= PARTIAL_MD5_SIZES[i]: for j in range( i, len( self.signatures ) ): self.signatures[j] = self.signatures[i] return self.signatures[i] # def getcrcsignature( self ): # if self.signatures[-1] is None: # self.signatures[-1] = getcrcsignature( self.filename ) # return self.signatures[-1] # def getcrcsignature( filename ): # f = open( filename, 'rb' ) # m = md5() # chunk = f.read( CHUNK_SIZE ) # while chunk: # m.update( chunk ) # chunk = f.read( CHUNK_SIZE ) # f.close() # return m.digest() def registerfile( file ): file.left = None file.right = None return file def errormsg( message, *args ): sys.stderr.write( '\r' + ( ' ' * 40 ) + '\r' + sys.argv[0] + ': ' ) print >>sys.stderr, message % args def escapechar( escape_list, c ): if c in escape_list: return '\\' + c return c def escapefilename( escape_list, filename ): return ''.join( map( escapechar, filename ) ) def grokfiles( input ): input = input[:] output = [] indicator = '-\\|/' if not options.hideprogress: progress = 0 while input: path = input.pop() if not options.hideprogress: if progress % 100 == 0: sys.stderr.write( '\rBuilding file list %c' % indicator[progress / 100 % len( indicator )] ) progress += 1 try: newfile = filestat( path ) if newfile.stat.st_size == 0 and options.excludeempty: continue lstat = os.lstat( path ) if stat.S_ISDIR( newfile.stat.st_mode ): if options.recurse and ( options.followlinks or not stat.S_ISLNK( lstat.st_mode ) ): try: for name in os.listdir( path ): input.append( os.path.join( path, name ) ) except OSError: errormsg( 'could not chdir to %s', path ) continue elif stat.S_ISREG( lstat.st_mode ) or ( stat.S_ISLNK( lstat.st_mode ) and options.followlinks ): output.append( newfile ) except OSError: pass return output def checkmatch( checktable, file ): if file.stat.st_size not in checktable: checktable[curfile.stat.st_size] = registerfile( file ) return None checktree = checktable[curfile.stat.st_size] while True: # If device and inode fields are equal one of the files is a # hard link to the other or the files have been listed twice # unintentionally. We don't want to flag these files as # duplicates unless the user specifies otherwise. if ( file.stat.st_ino == checktree.stat.st_ino and file.stat.st_dev == checktree.stat.st_dev ): if options.considerhardlinks: return checktree else: return None try: cmpresult = 0 for i in range( len( PARTIAL_MD5_SIZ
Re: Поиск и удаление дублирующих файлов
On Sun, Nov 06, 2011 at 08:31:09PM +0600, Andrey Rahmatullin wrote: > > > Какие программы есть на эту тему? Желательно, чтоб можно > > > было посмотреть список файлов-дубляжей и выборочно удалить > > > любой из них. > > Несколько не в тему. Вместо удаления повторов, я обычно > > заменяю их одним файлом с несколькими именами (e. g., > > через ln(1)) предварительно проверив совпадение mtime и > > содержимого. (И, конечно, то, что это /различные/ файлы.) > apt-get install hardlink JFYI, ldv@ некоторое время тому рекомендовал вместо него hardlinkpy. В дебиане будто не наблюдаю -- http://hardlinkpy.googlecode.com/ -- WBR, Michael Shigorin -- Linux.Kiev http://www.linux.kiev.ua/ -- 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/2019130757.gd11...@osdn.org.ua
Re: Поиск и удаление дублирующих файлов
On Sun, Nov 06, 2011 at 12:35:06AM +0700, Ivan Shmakov wrote: > > Нагашибай Жанибек writes: > > > Какие программы есть на эту тему? Желательно, чтоб можно было > > посмотреть список файлов-дубляжей и выборочно удалить любой из них. > > Несколько не в тему. Вместо удаления повторов, я обычно заменяю > их одним файлом с несколькими именами (e. g., через ln(1)) > предварительно проверив совпадение mtime и содержимого. (И, > конечно, то, что это /различные/ файлы.) apt-get install hardlink -- WBR, wRAR signature.asc Description: Digital signature
Re: Поиск и удаление дублирующих файлов
05.11.2011 21:07, Yuriy Kaminskiy пишет: 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 " 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 ... не окажется ли FN до первого пробела в имени файла? if [ "$MD5" = "$MD5PRE" ] then # если мд5 текущего и предыдущего совпали # но имя предыдущего файла не пустое, значит выводим две строки # и опустошаем имя предыдущего файла чтобы по этому признаку определить # что нужно выводить одну строку а не две if [ "$FNPRE" != "" ] if [ -n "$FNPRE" ] then ... но я бы для поиска дупликатов заюзал uniq -w32 -D :-) понял, понравилось, но тут более далекая задумка, а именно: fille и dup - впоследствии заменить командами, например dup внутри выполняет rm -f $1 Но это примитивно, а задумал я впоследствии такой проект: собирать базу файлов на всех компах где я работаю и иметь что-то вроде распределенного хранилища этой базы, как git или mercurial. Т.е. отсканировал дома файлы и кинул на работу список, затем отсканировал на работе и импортировал домашний список. В итоге я запускаю свой поиск и вижу что на работе у меня есть те же файлы что и дома или каких-то не хватает. В свою очередь я домой отправляю список рабочих файлов и могу увидеть каких у меня не хватает дома. Аналогичные операции я проделываю на бекап-машине и докидываю туда то что хотел бы сохранить при крахе. Но и это еще не все. Имея такую базу можно не только производить поиск не имея доступа к удаленной машине, но и вести класси
Re: Поиск и удаление дублирующих файлов
> Иван Лох writes: > On Sun, Nov 06, 2011 at 12:35:06AM +0700, Ivan Shmakov wrote: >> Несколько не в тему. Вместо удаления повторов, я обычно заменяю их >> одним файлом с несколькими именами (e. g., через ln(1)) >> предварительно проверив совпадение mtime и содержимого. (И, >> конечно, то, что это /различные/ файлы.) >> Эта операция, если выполняется правильно (в частности, что очевидно, >> файлы не должны меняться в процессе проверки), не допускает потери >> данных. > Да, но > $ echo "1:1" >site1/passwd > $ echo "1:1" >site2/passwd > $ Поискали > $ rm site2/passwd && ln site1/passwd site2/passwd rm(1) не требуется. ln(1) атомарно изменит второе имя файла так, чтобы оно ссылалось на тот же файл, что и первое. > $ ... > $ echo "2:2" >site2/passwd > $ cat site1/passwd > Оп! Этого ли Вы хотели? Во-первых, такого рода замену я выполняю только в тех директориях, в которых файлы de facto являются read-only. Вроде ~/public/files/ (который у меня вместо ~/Downloads/.) Во-вторых: $ echo 2:2 > site2/passwd.tmp && mv -- site2/passwd.tmp site2/passwd По крайней мере так поступают программы, вроде mv(1), rsync(1), да и некоторые текстовые редакторы, полагаю, при соответствующей настройке. В противном случае несложно оказаться в ситуации, когда старое содержимое уже удалено, а новое не удалось записать по причине, e. g., отсутствия свободного пространства на ФС. Поэтому, такое поведение программы для меня — повод написать отчет в BTS. -- FSF associate member #7257 pgpBjkW7B4SYN.pgp Description: PGP signature
Re: Поиск и удаление дублирующих файлов
On Sun, Nov 06, 2011 at 12:35:06AM +0700, Ivan Shmakov wrote: > > Несколько не в тему. Вместо удаления повторов, я обычно заменяю > их одним файлом с несколькими именами (e. g., через ln(1)) > предварительно проверив совпадение mtime и содержимого. (И, > конечно, то, что это /различные/ файлы.) > > Эта операция, если выполняется правильно (в частности, что > очевидно, файлы не должны меняться в процессе проверки), не > допускает потери данных. Да, но $ echo "1:1" >site1/passwd $ echo "1:1" >site2/passwd $ Поискали $ rm site2/passwd && ln site1/passwd site2/passwd $ ... $ echo "2:2" >site2/passwd $ cat site1/passwd Оп! Этого ли Вы хотели? -- Иван Лох -- 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/2005174712.gc1...@nano.ioffe.rssi.ru
Re: Поиск и удаление дублирующих файлов
> Нагашибай Жанибек writes: > Какие программы есть на эту тему? Желательно, чтоб можно было > посмотреть список файлов-дубляжей и выборочно удалить любой из них. Несколько не в тему. Вместо удаления повторов, я обычно заменяю их одним файлом с несколькими именами (e. g., через ln(1)) предварительно проверив совпадение mtime и содержимого. (И, конечно, то, что это /различные/ файлы.) Эта операция, если выполняется правильно (в частности, что очевидно, файлы не должны меняться в процессе проверки), не допускает потери данных. -- FSF associate member #7257 pgpMMzCZCCboD.pgp Description: PGP signature
Re: Поиск и удаление дублирующих файлов
> > Какие программы есть на эту тему? Желательно, чтоб можно было > > посмотреть список файлов-дубляжей и выборочно удалить любой из них. > > > > > > Моё творение: > > #! /bin/bash > > # Алгоритм работы скрипта: > # 1. Составить список файлов > # 2. Вычислить все md5 суммы файлов Сходу: это надо делать только после того, как отфильтрованы файлы, чей размер не совпадает ни с каким другим. Большие файлы обычно характерны тем, что шансов на совпадение размера у них немного, а считать даже 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 " > 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` wc -l Ну, про то, что твоя программа грохается на файлах, содержащих перевод строки в имени, я просто в скобках замечу. Да, это извращение, но это вполне легитимный символ в имени файла. -- Чушь для ресниц (С)энта -- 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/87wrbeiix6.wl%...@ran.pp.ru
Re: Поиск и удаление дублирующих файлов
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 " > 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
Re: Поиск и удаление дублирующих файлов
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 " 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"
Re: Поиск и удаление дублирующих файлов
В Sat, 5 Nov 2011 10:13:36 +0600 Нагашибай Жанибек пишет: > Какие программы есть на эту тему? Желательно, чтоб можно было > посмотреть список файлов-дубляжей и выборочно удалить любой из них. > > Моё творение: #! /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 " 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" -- 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/2005174522.5252d227@serega-pc
Re: Поиск и удаление дублирующих файлов
On 05.11.2011 08:13, Нагашибай Жанибек wrote: Какие программы есть на эту тему? Желательно, чтоб можно было посмотреть список файлов-дубляжей и выборочно удалить любой из них. Гугли морды к fdupes или подобное. -- 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/4eb4f4af.7090...@yandex.ru
Re: Поиск и удаление дублирующих файлов
On Sat, 5 Nov 2011 10:13:36 +0600 Нагашибай Жанибек wrote: >Какие программы есть на эту тему? Желательно, чтоб можно было >посмотреть список файлов-дубляжей и выборочно удалить любой из них. > > fdupes pgpGqd7KUceTr.pgp Description: PGP signature