2013-01-12 1 views
1

В Linux среде мне нужно будет удалить дубликаты изображений с помощью md5 файла, но перед удалением, я хочу написать в файле какой-то список CSV изудаление дубликатов изображений с помощью кли

Удалено Файл -> Linked Первый файл Удалено Файл -> Linked File

Etc.

проблема заключается в том, что у меня есть структура

Главная Папка вложенная_папка Sub-Sub Folder Sub-Sub-Sub Folder
Изображения

С более чем 200.000 файлов

Так скрипт должен быть достаточно хорошо, чтобы не висеть и быть быстрым.

В каком направлении вы бы предложили?

У меня есть ubuntu под рукой.

UPDATE:

Я нашел скрипт, который делает с небольшой модификацией, что мне нужно. Он ищет и находит дубликаты md5 и удаляет дубликаты. Только последний шаг, необходимый, чтобы сделать файл со списком удаленного файла -> дубликат, который остается

#!/bin/bash 

DIR="/home/gevork/Desktop/webserver/maps.am/all_tiles/dubai_test" 

find $DIR -type f -exec md5sum {} \; | sort > /home/gevork/Desktop/webserver/maps.am/all_tiles/dubai_test/sums-sorted.txt 

OLDSUM="" 
IFS=$'\n' 
for i in `cat /home/gevork/Desktop/webserver/maps.am/all_tiles/dubai_test/sums-sorted.txt`; do 
NEWSUM=`echo "$i" | sed 's/ .*//'` 
NEWFILE=`echo "$i" | sed 's/^[^ ]* *//'` 
if [ "$OLDSUM" == "$NEWSUM" ]; then 
    echo rm "$NEWFILE" 
else 
    OLDSUM="$NEWSUM" 
    OLDFILE="$NEWFILE" 
fi 
done 
+0

У вас есть изображения в 'Main Folder', а также в' Subfolder' 'Main Folder' и т. Д.? Кроме того, вы хотите решить, является ли файл изображением или вы знаете, что все файлы в этих папках являются изображениями? Или вы просто хотите удалить дубликаты файлов, независимо от того, что они? – mmgp

+0

@mmgp Все файлы находятся в концевой подпапке уровня 3. Все изображения размером 256X256. Мне нужно удалить дубликаты по md5 и написать текстовый файл, где будет список удаленных файлов -> не удаленный дубликат –

+0

Являются ли они точные копии, то есть даже данные exif не изменены? Я не вижу причины, по которой это будет помечено как обработка изображений. – mmgp

ответ

0

Я нахожу Python хороший инструмент для решения этих задач, и более компактен, тоже (хотя вы ограничили вопрос Linux). В приведенном ниже коде будет храниться самый старый файл (по времени создания) среди дубликатов, если это не имеет значения для вас, тогда его можно упростить. Чтобы использовать его, сохраните его, например, «remove_dups.py», и запустите его как python remove_dumps.py startdir. От startdir он будет искать каталоги, которые будут располагаться на 3 уровнях, и вычислить сумму md5 содержимого там. Он хранит список имен файлов на хэш. Текстовый файл, который вы используете, печатается в стандартном режиме, поэтому вы действительно хотите запустить его как python remove_dumps.py startdir > myoutputfile.txt. Он также сохранит исходный каталог в этом выходном файле. Каждая другая строка форматируется как: md5sum: file1, file2, file3, ... для дубликатов файлов. Первый из них хранится, остальные удаляются.

import os 
import sys 
import glob 
import hashlib 
from collections import defaultdict 

BIG_ENOUGH_CTIME = 2**63-1 

start_dir = sys.argv[1] 

hash_file = defaultdict(list) 
level3_files = glob.glob(os.path.join(start_dir, "*", "*", "*", "*")) 
for name in level3_files: 
    try: 
     md5 = hashlib.md5(open(name).read()).hexdigest() 
    except Exception, e: 
     sys.stderr.write("Failed for %s. %s\n" % (name, e)) 
    else: 
     # If you don't care about keeping the oldest between the duplicates, 
     # the following files can be simplified. 
     try: 
      ctime = os.stat(name).st_ctime 
     except Exception, e: 
      sys.stderr.write("%s\n" % e) 
      hash_file[md5].append((BIG_ENOUGH_CTIME, name)) 
     else: 
      hash_file[md5].append((ctime, name)) 

print "base: %s" % (os.path.abspath(start_dir)) 
for md5, l in hash_file.items(): 
    if len(l) == 1: 
     continue 

    # Keep the oldest file between the duplicates. 
    l = sorted(l) 
    name = [data[1] for data in l] 

    # md5sum: list of files. The first in the list is kept, the others are 
    # removed. 
    print "%s: %s" % (md5, ','.join('"%s"' % n for n in name)) 

    original = name.pop(0) 
    for n in name: 
     print "%s->%s" % (n, original) 
     sys.stderr.write("Removing %s\n" % n) 
     try: 
      os.remove(n) 
     except Exception, e: 
      sys.stderr.write("%s\n" % e) 
+0

Но после удаления файлов мне понадобится файл txt со списком, где будет указано DELETED_FILE-> ORIGINAL; DELETED2-> ORIGINAL2; –

+0

Этот список уже создан, только в другом формате. Вы хотите, чтобы я скорректировал код для этого конкретного формата или вы говорите, что это невозможно сделать с помощью этого кода? – mmgp

+0

, если бы вы отрегулировали, это было бы большой услугой для меня :) Во всяком случае, я бы хотел поблагодарить вас. –

 Смежные вопросы

  • Нет связанных вопросов^_^