重複ファイルを一覧化

無秩序にとりあえずファイルを格納していたフォルダを整理するため、重複したファイルを一覧表示してみた。

目次

  1. ソース
  2. 補足説明
  3. 残課題

ソース

import os
import csv
import hashlib
from collections import defaultdict

root_path = 'C:\\Path\\to\\Dir'
csv_file_name = 'list_duplicated_files.csv'
file_dict = defaultdict(list)

for root, dirs, files in os.walk(root_path):
    for file in files:
        path = os.path.join(root, file)
        try:
            with open(path, 'rb') as f:
                key = hashlib.md5(f.read()).hexdigest()
                file_dict[key].append((root, file, os.path.getsize(path)))
        except PermissionError:
            print('Permission denied:', path)
        except UnicodeEncodeError:
            print('UnicodeEncodeError:', path)

with open(csv_file_name, 'w', newline='', encoding='utf-8') as csv_file:
    writer = csv.writer(csv_file)
    for key, values in filter(lambda item: len(item[1]) > 1, file_dict.items()):
        for value in values:
            try:
                writer.writerow((key,)+value)
            except UnicodeEncodeError:
                print('UnicodeEncodeError:', value[0], value[1])

補足説明

同一ファイルであることの判別にhashlibモジュールによるMD5値を用いている。MD5値を辞書のkeyにして格納しておき、同一MD5値の数が1より大きい場合のみCSVファイルへ出力するようにしている。
import hashlib
...
                key = hashlib.md5(f.read()).hexdigest()
                file_dict[key].append((root, file, os.path.getsize(path)))
...
    for key, values in filter(lambda item: len(item[1]) > 1, file_dict.items()):
...

辞書にはdefaultdictというvalueに初期値設定可能なコレクションを利用。keyにMD5値、valueにフォルダパス、ファイル名、ファイルサイズのtupleのlistを格納しているが、defaultdictを利用することで、for文の中で初めてのMD5値を格納する場合でも、listを新規作成して格納する手間が省ける(appendをすぐコールできる)。
from collections import defaultdict
...
                key = hashlib.md5(f.read()).hexdigest()
                file_dict[key].append((root, file, os.path.getsize(path)))

残課題

utf-8でCSVを書き出しているが、これをそのままExcelで開こうとすると、Excelの仕様でsjisで開こうとするらしく、文字化けしてしまう。sjisで出力しようとしたけどもなかなかうまく行かなかった。。

コメント

このブログの人気の投稿

Python SQLite スレッド間でコネクションの使いまわしは出来ない

slackでgeneralの投稿を全削除する

Google location history(JSON形式)をCSVファイルにする