Search
 
SCRIPT & CODE EXAMPLE
 

PYTHON

python find duplicated zip files

#!/usr/bin/env python
# if running in py3, change the shebang, drop the next import for readability (it does no harm in py3)
from __future__ import print_function   # py2 compatibility
from collections import defaultdict
import hashlib
import os
import sys


def chunk_reader(fobj, chunk_size=1024):
    """Generator that reads a file in chunks of bytes"""
    while True:
        chunk = fobj.read(chunk_size)
        if not chunk:
            return
        yield chunk


def get_hash(filename, first_chunk_only=False, hash=hashlib.sha1):
    hashobj = hash()
    file_object = open(filename, 'rb')

    if first_chunk_only:
        hashobj.update(file_object.read(1024))
    else:
        for chunk in chunk_reader(file_object):
            hashobj.update(chunk)
    hashed = hashobj.digest()

    file_object.close()
    return hashed


def check_for_duplicates(paths, hash=hashlib.sha1):
    hashes_by_size = defaultdict(list)  # dict of size_in_bytes: [full_path_to_file1, full_path_to_file2, ]
    hashes_on_1k = defaultdict(list)  # dict of (hash1k, size_in_bytes): [full_path_to_file1, full_path_to_file2, ]
    hashes_full = {}   # dict of full_file_hash: full_path_to_file_string

    for path in paths:
        for dirpath, dirnames, filenames in os.walk(path):
            # get all files that have the same size - they are the collision candidates
            for filename in filenames:
                full_path = os.path.join(dirpath, filename)
                try:
                    # if the target is a symlink (soft one), this will 
                    # dereference it - change the value to the actual target file
                    full_path = os.path.realpath(full_path)
                    file_size = os.path.getsize(full_path)
                    hashes_by_size[file_size].append(full_path)
                except (OSError,):
                    # not accessible (permissions, etc) - pass on
                    continue


    # For all files with the same file size, get their hash on the 1st 1024 bytes only
    for size_in_bytes, files in hashes_by_size.items():
        if len(files) < 2:
            continue    # this file size is unique, no need to spend CPU cycles on it

        for filename in files:
            try:
                small_hash = get_hash(filename, first_chunk_only=True)
                # the key is the hash on the first 1024 bytes plus the size - to
                # avoid collisions on equal hashes in the first part of the file
                # credits to @Futal for the optimization
                hashes_on_1k[(small_hash, size_in_bytes)].append(filename)
            except (OSError,):
                # the file access might've changed till the exec point got here 
                continue

    # For all files with the hash on the 1st 1024 bytes, get their hash on the full file - collisions will be duplicates
    for __, files_list in hashes_on_1k.items():
        if len(files_list) < 2:
            continue    # this hash of fist 1k file bytes is unique, no need to spend cpy cycles on it

        for filename in files_list:
            try: 
                full_hash = get_hash(filename, first_chunk_only=False)
                duplicate = hashes_full.get(full_hash)
                if duplicate:
                    print("Duplicate found: {} and {}".format(filename, duplicate))
                else:
                    hashes_full[full_hash] = filename
            except (OSError,):
                # the file access might've changed till the exec point got here 
                continue


if __name__ == "__main__":
    if sys.argv[1:]:
        check_for_duplicates(sys.argv[1:])
    else:
        print("Please pass the paths to check as parameters to the script")
Comment

PREVIOUS NEXT
Code Example
Python :: how to convert exe file to python file 
Python :: introduction to sets python3 
Python :: star psf 
Python :: Dateien mit modul requests herunterladen python 
Python :: pandas boolean array calculating the average of a column based on another column filter 
Python :: how to show Screen keyboard ubuntu with python 
Python :: what is norways politics 
Python :: uninstall python 2.7 in ubuntu 
Python :: generic rectangle 
Python :: ex: for stopping the while loop after 5 minute in python 
Python :: py urllib download foto 
Python :: sphix dont see .py file 
Python :: download image from url python 
Python :: drop values based on type pandas 
Python :: python last letter of string 
Python :: latch in rospy.publisher 
Python :: how do you amke function in python 
Python :: how to use event of Button in python 
Python :: how list comprehension for 2D works 
Python :: see python function details in vscode 
Python :: Using rstrip() method to remove the newline character from a string 
Python :: django domain name 
Python :: python top label plot 
Python :: python format method align center 
Python :: transverse tensor in pytorch 
Python :: how to import autpy 
Python :: How to get a mock image in django? 
Python :: grandest staircase foobar 
Python :: python bangla packages 
Python :: how to delete a row based on a criteria in python datafram 
ADD CONTENT
Topic
Content
Source link
Name
8+1 =