最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python自動化辦公之清理重復文件詳解

 更新時間:2022年05月10日 15:32:18   作者:渴望力量的哈士奇  
這篇文章主要為大家詳細介紹了如何利用Python清理重復的文件,文中的示例代碼講解詳細,對我們學習Python有一定幫助,需要的可以參考一下

清理重復的文件

已知條件:

什么都不知道,只需要知道它是文件就可以了

實現(xiàn)方法:

可以從指定路徑(或最上層路徑)開始讀取,利用 glob 讀取每個文件夾,讀到文件,記錄名稱和大小,每一次檢測之前是否讀取過相同名稱的文件,如果存在,判斷大小是否相同,如果相同,我們就認為這是重復文件,將其刪除。

代碼示例如下:

# coding:utf-8

import glob
import os.path

data = {}       # 定義一個空的字典,暫時將文件名存進來

def clear(path):
    result = glob.glob(path)    # 將 path 路徑傳入,賦值給 result

    for _data in result:    # for 循環(huán)判斷是否是文件夾
        if glob.os.path.isdir(_data):   # 若是文件夾,繼續(xù)將該文件夾的路徑傳給 clear() 函數(shù)繼續(xù)遞歸查找
            _path = glob.os.path.join(_data, '*')
            clear(_path)
        else:                           # 若是文件,則將文件名提取出來
            name = glob.os.path.split(_data)[-1]


            if 'zip' in name:         # 因為目前我們測試的 path 下有 ".zip" 文件,所以這里跳過 '.zip' 壓縮文件的讀取否則會報錯
                continue

            f = open(_data, 'r')      # 判斷文件名之前先將內(nèi)容讀取出來,若是不可讀模式
            content = f.read()        # 將讀取內(nèi)容賦值給 content

            if name in data:          # 判斷文件名是否已存在 data 這個臨時存儲文件名的字典內(nèi),如果存在則進行執(zhí)行刪除動作
                _content_dict = data[name]

                if _content_dict == content:
                    print('文件 \"{}\" 被刪除...'.format(_data))     # 調(diào)試
                    os.remove(_data)
            else:
                data[name] = content


if __name__ == '__main__':
    path = glob.os.path.join(glob.os.getcwd(), 'test_file')
    clear(path)

PS:這里需要注意一下,如果path的路徑是根目錄的話,會出現(xiàn)超級意外的結(jié)果,建議還是建立一個單獨的文件夾路徑來測試吧。(這個坑踩的我很心痛....)

運行結(jié)果如下:

清理重復文件的優(yōu)化1

解決不同路徑下相同文件名不同內(nèi)容問題

其實在這里大家能夠想到一個問題,可能會存在這樣一種情況,在不同的文件夾下存在著相同文件名,但是文件的內(nèi)容卻是不相同的。如果利用上面的腳本執(zhí)行針對文件夾下相同文件名的文件進行刪除的話,其實是一種不嚴謹?shù)牟僮鳌?/p>

由此也就引出了我們接下來針對上文腳本優(yōu)化的需求。

這里我們先看一下實際情況的 data 的值應該是怎樣的:data = {'name': {'path/name': 'content', 'path2/name': 'content'}}

  • 上行內(nèi)容的 name 為我們傳入路徑的根路徑
  • 上行內(nèi)容的 path/name 實際上為二級路徑
  • 上行內(nèi)容的 content 為文件內(nèi)容

通過這種二級路徑與內(nèi)容刪除的重復文件才是一種比較合理的方式。

示例代碼如下:

# coding:utf-8

import glob
import os.path

data = {}       # 定義一個空的字典,暫時將文件名存進來


def clear(path):
    result = glob.glob(path)    # 將 path 路徑傳入,賦值給 result

    for _data in result:    # for 循環(huán)判斷是否是文件夾
        if glob.os.path.isdir(_data):   # 若是文件夾,繼續(xù)將該文件夾的路徑傳給 clear() 函數(shù)繼續(xù)遞歸查找
            _path = glob.os.path.join(_data, '*')
            clear(_path)
        else:                           # 若是文件,則將文件名提取出來
            name = glob.os.path.split(_data)[-1]


            if 'zip' in name:         # 因為目前我們測試的 path 下有 ".zip" 文件,所以這里跳過 '.zip' 壓縮文件的讀取否則會報錯
                continue

            f = open(_data, 'r')      # 判斷文件名之前先將內(nèi)容讀取出來,若是不可讀模式
            content = f.read()        # 將讀取內(nèi)容賦值給 content

            if name in data:        # 判斷文件名是否已存在 data 這個臨時存儲文件名的字典內(nèi),如果存在則進行執(zhí)行刪除動作
                                    # 如果不存在,則將讀取到的二級路徑與內(nèi)容存儲至 data 這個空字典內(nèi)
                sub_name = data[name]       # 定義 sub_name 用以獲取二級路徑

                is_delete = False   # is_delete 用以記錄刪除狀態(tài);如果沒有刪除,還需要將二級路徑添加至 data

                for k, v in sub_name.items():    # 再次循環(huán)判斷二級路徑下的文件;k 為路徑,v 為文件內(nèi)容
                    print('二級路徑為 \"{}\" ,'.format(k), name, '內(nèi)容為 \'{}\' '.format(v))   # 調(diào)試打印輸出二級路徑下文件的循環(huán)
                    if v == content:             # 如果文件名與內(nèi)容相同,則執(zhí)行刪除動作
                        print('文件 \"{}\" 被刪除...'.format(_data))     # 調(diào)試被刪除的文件
                        os.remove(_data)      # 刪除重復文件后,變更 is_delete 狀態(tài)為True
                        is_delete = True

                if not is_delete:       # 如果沒有刪除則將 content 讀取到的內(nèi)容賦值給 data[name][_data]
                    data[name][_data] = content
            else:
                data[name] = {
                    _data: content
                }


if __name__ == '__main__':
    path = glob.os.path.join(glob.os.getcwd(), 'test_file')
    clear(path)
    print(data)

運行結(jié)果如下:

清理重復文件的優(yōu)化2

利用 hashlib模塊解決讀取文件過大問題

現(xiàn)在還有一個問題,從調(diào)試的打印輸出內(nèi)容可以看出,因為用以測試的 test_file 路徑下的文件都比較小,所以運行起來沒有太大的問題;試想一下,如果是一些比較大的文件,經(jīng)過讀取并存入字典的時候,就極大可能會造成內(nèi)存不足等情況,所以這樣直接存儲內(nèi)容的方法是顯然不合適的。

其實也是可以解決這個問題的, 就是利用到之前學習的加密模塊 ,通過 hashlib 模塊將內(nèi)容加密成md5 的形式, md5只是一個很短的字符串,只要原始內(nèi)容不變, md5 的值就不會變(該方法也經(jīng)常被用于運維環(huán)境的文件安全檢測)。

所以代碼中的讀取文件內(nèi)容的 content 就需要變更一下了:

代碼示例如下:

# coding:utf-8

import glob
import hashlib
import os.path

data = {}       # 定義一個空的字典,暫時將文件名存進來
#data = {'name': {'path/name': 'content', 'path2/name': 'content'}}

def clear(path):
    result = glob.glob(path)    # 將 path 路徑傳入,賦值給 result

    for _data in result:    # for 循環(huán)判斷是否是文件夾
        if glob.os.path.isdir(_data):   # 若是文件夾,繼續(xù)將該文件夾的路徑傳給 clear() 函數(shù)繼續(xù)遞歸查找
            _path = glob.os.path.join(_data, '*')
            clear(_path)
        else:                           # 若是文件,則將文件名提取出來
            name = glob.os.path.split(_data)[-1]


            if 'zip' in name:         # 因為目前我們測試的 path 下有 ".zip" 文件,所以這里跳過 '.zip' 壓縮文件的讀取否則會報錯
                continue

            f = open(_data, 'r')      # 判斷文件名之前先將內(nèi)容讀取出來,若是不可讀模式
            content = f.read()        # 將讀取內(nèi)容賦值給 content

            hash_content_obj = hashlib.md5(content.encode('utf-8'))     # 將讀取到的文件內(nèi)容通過 md5 加密形式進行實例化
            hash_content = hash_content_obj.hexdigest()                 # hash_content_obj 16進制字符串賦值給 hash_content
                                                                        # 到這里,其實 data 存儲的就是 hash_content

            if name in data:        # 判斷文件名是否已存在 data 這個臨時存儲文件名的字典內(nèi),如果存在則進行執(zhí)行刪除動作
                                    # 如果不存在,則將讀取到的二級路徑與內(nèi)容存儲至 data 這個空字典內(nèi)
                sub_name = data[name]       # 定義 sub_name 用以獲取二級路徑

                is_delete = False   # is_delete 用以記錄刪除狀態(tài);如果沒有刪除,還需要將二級路徑添加至 data

                for k, v in sub_name.items():    # 再次循環(huán)判斷二級路徑下的文件;k 為路徑,v 為文件內(nèi)容
                    print('二級路徑為 \"{}\" ,'.format(k), name, '內(nèi)容為 \'{}\' '.format(v))   # 調(diào)試打印輸出二級路徑下文件的循環(huán)
                    if v == hash_content:             # 如果文件名與內(nèi)容相同,則執(zhí)行刪除動作
                        print('文件 \"{}\" 被刪除...'.format(_data))     # 調(diào)試被刪除的文件
                        os.remove(_data)      # 刪除重復文件后,變更 is_delete 狀態(tài)為True
                        is_delete = True

                if not is_delete:       # 如果沒有刪除則將 content 讀取到的內(nèi)容賦值給 data[name][_data]
                    data[name][_data] = hash_content
            else:
                data[name] = {
                    _data: hash_content
                }


if __name__ == '__main__':
    path = glob.os.path.join(glob.os.getcwd(), 'test_file')
    clear(path)
    print(data)

運行結(jié)果如下:

清理重復文件的優(yōu)化3

解決讀取到不可讀的 “zip” 文件報錯問題

在上文中,當我們遇到讀取到不可讀的 “zip” 壓縮文件時,利用的是 continue 的方式跳過。 其實這里說的 “zip” 不可讀取其實不太嚴謹,因為可以采用二進制讀取的方式來進行讀取,但是在上文腳本中,針對讀取的內(nèi)容已經(jīng)進行了 “encode” 編碼,所以用 rb 這種二進制讀取的方式還需要繼續(xù)進行優(yōu)化。

示例代碼如下:

# coding:utf-8

import glob
import hashlib

#data = {'name': {'path/name': 'content', 'path2/name': 'content'}}
import os.path

data = {}       # 定義一個空的字典,暫時將文件名存進來


def clear(path):
    result = glob.glob(path)    # 將 path 路徑傳入,賦值給 result

    for _data in result:    # for 循環(huán)判斷是否是文件夾
        if glob.os.path.isdir(_data):   # 若是文件夾,繼續(xù)將該文件夾的路徑傳給 clear() 函數(shù)繼續(xù)遞歸查找
            _path = glob.os.path.join(_data, '*')
            clear(_path)
        else:                           # 若是文件,則將文件名提取出來
            name = glob.os.path.split(_data)[-1]

            is_byte = False            # 添加一個 byte類型讀取的開關(guān)(如果文件中有中文,還需要設(shè)置一下編碼格式,并且將打開的文件關(guān)閉)

            if 'zip' in name:           # 因為目前我們測試的 path 下有 ".zip" 文件,所以這里跳過 '.zip' 壓縮文件的讀取否則會報錯
                is_byte = True
                f = open(_data, 'rb')
            else:
                f = open(_data, 'r', encoding='utf-8')      # 判斷文件名之前先將內(nèi)容讀取出來,若是不可讀模式
            content = f.read()        # 將讀取內(nèi)容賦值給 content
            f.close()

            if is_byte:
                hash_content_obj = hashlib.md5(content)     # 將讀取到的文件內(nèi)容通過 md5 加密形式進行實例化
            else:
                hash_content_obj = hashlib.md5(content.encode('utf-8'))

            hash_content = hash_content_obj.hexdigest()                 # hash_content_obj 16進制字符串賦值給 hash_content
                                                                        # 到這里,其實 data 存儲的就是 hash_content

            if name in data:        # 判斷文件名是否已存在 data 這個臨時存儲文件名的字典內(nèi),如果存在則進行執(zhí)行刪除動作
                                    # 如果不存在,則將讀取到的二級路徑與內(nèi)容存儲至 data 這個空字典內(nèi)
                sub_name = data[name]       # 定義 sub_name 用以獲取二級路徑

                is_delete = False   # is_delete 用以記錄刪除狀態(tài);如果沒有刪除,還需要將二級路徑添加至 data

                for k, v in sub_name.items():    # 再次循環(huán)判斷二級路徑下的文件;k 為路徑,v 為文件內(nèi)容
                    print('二級路徑為 \"{}\" ,'.format(k), name, '內(nèi)容為 \'{}\' '.format(v))   # 調(diào)試打印輸出二級路徑下文件的循環(huán)
                    if v == hash_content:             # 如果文件名與內(nèi)容相同,則執(zhí)行刪除動作
                        print('文件 \"{}\" 被刪除...'.format(_data))     # 調(diào)試被刪除的文件
                        os.remove(_data)      # 刪除重復文件后,變更 is_delete 狀態(tài)為True
                        is_delete = True

                if not is_delete:       # 如果沒有刪除則將 content 讀取到的內(nèi)容賦值給 data[name][_data]
                    data[name][_data] = hash_content
            else:
                data[name] = {
                    _data: hash_content
                }


if __name__ == '__main__':
    path = glob.os.path.join(glob.os.getcwd(), 'test_file')
    clear(path)

    for k, v in data.items():
        for _k, v in v.items():
            print('文件路徑為 \"{}\" ,'.format(_k), '內(nèi)容為 \'{}\' '.format(v))

運行結(jié)果如下:

批量修改文件名

其實也很簡單,依然是使用我們最近學習的 shutil 與 glob 模塊(參考上一章節(jié)的文件查找與遞歸實現(xiàn)的方式)。

已知條件:

知道文件名需要被修改的指定字符串(即需要被修改的文件名)

實現(xiàn)方法:

通過循環(huán),將指定的目標字符串加入或修改文件名稱中含有的字符串

代碼示例如下:

# coding:utf-8

import glob
import os.path
import shutil


'''
    利用for循環(huán)及遞歸這樣的方式,通過 glob 去讀取到 test_file 下所有的內(nèi)容
    通過循環(huán)按照循環(huán)的每一個索引,把每一個文件添加上索引標
'''

def filename_update(path):
    result = glob.glob(path)

    for index, data in enumerate(result):     # for 循環(huán)枚舉:如果是文件夾則進行遞歸,如果是文件則加上索引值
        if glob.os.path.isdir(data):
            _path = glob.os.path.join(data, '*')
            filename_update(_path)
        else:
            path_list = glob.os.path.split(data)
            name = path_list[-1]
            new_name = '{}_{}'.format(index, name)
            new_data = glob.os.path.join(path_list[0], new_name)
            shutil.move(data, new_data)


if __name__ == '__main__':
    path = glob.os.path.join(glob.os.getcwd(), 'test_file')
    filename_update(path)

運行結(jié)果如下:

可能這里大家有注意到 "test_file" 文件加下沒有 "0_*"開頭的索引,其實并不是沒有索引,而是我們的腳本中只重命名了文件,文件夾被過濾掉了。

到此這篇關(guān)于Python自動化辦公之清理重復文件詳解的文章就介紹到這了,更多相關(guān)Python清理重復文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python 基礎(chǔ)教程之str和repr的詳解

    Python 基礎(chǔ)教程之str和repr的詳解

    這篇文章主要介紹了Python 基礎(chǔ)教程之str和repr的詳解的相關(guān)資料,主要說明他們之家的區(qū)別,通過此文希望能幫助到大家,幫助大家理解這部分內(nèi)容,需要的可以參考下
    2017-08-08
  • Python利用百度地圖獲取兩地距離(附demo)

    Python利用百度地圖獲取兩地距離(附demo)

    本文主要介紹了Python利用百度地圖獲取兩地距離,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • 基于Python制作一個文件去重小工具

    基于Python制作一個文件去重小工具

    我們常常在下載網(wǎng)絡(luò)素材時會下載很多的重復文件亂七八糟的,于是想實現(xiàn)一個去重的操作就顯得很重要。本文將用Python制作一個簡單的文件去重小工具,需要的可以參考一下
    2022-02-02
  • 在Django中實現(xiàn)添加user到group并查看

    在Django中實現(xiàn)添加user到group并查看

    今天小編就為大家分享一篇在Django中實現(xiàn)添加user到group并查看,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • python常用數(shù)據(jù)結(jié)構(gòu)元組詳解

    python常用數(shù)據(jù)結(jié)構(gòu)元組詳解

    這篇文章主要介紹了python常用數(shù)據(jù)結(jié)構(gòu)元組詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • 淺談python類屬性的訪問、設(shè)置和刪除方法

    淺談python類屬性的訪問、設(shè)置和刪除方法

    下面小編就為大家?guī)硪黄獪\談python類屬性的訪問、設(shè)置和刪除方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • Python實現(xiàn)加載及解析properties配置文件的方法

    Python實現(xiàn)加載及解析properties配置文件的方法

    這篇文章主要介紹了Python實現(xiàn)加載及解析properties配置文件的方法,結(jié)合實例形式分析了Python針對properties配置文件的加載、讀取及解析相關(guān)操作技巧,需要的朋友可以參考下
    2018-03-03
  • Python中使用動態(tài)變量名的方法

    Python中使用動態(tài)變量名的方法

    這篇文章主要介紹了Python中使用動態(tài)變量名的方法,需要的朋友可以參考下
    2014-05-05
  • Python多線程的使用詳情

    Python多線程的使用詳情

    這篇文章主要介紹了Python多線程的使用詳情,線程之間執(zhí)行是無序的,cpu調(diào)度哪個線程就執(zhí)行哪個線程,下文相關(guān)介紹需要的小伙伴可以參考一下
    2022-04-04
  • Python實現(xiàn)鏈表反轉(zhuǎn)與合并操作詳解

    Python實現(xiàn)鏈表反轉(zhuǎn)與合并操作詳解

    這篇文章主要為大家詳細介紹了?Python?中反轉(zhuǎn)鏈表和合并鏈表的應用場景及實現(xiàn)方法,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2025-02-02

最新評論

襄城县| 方正县| 淮阳县| 辉县市| 东阿县| 铁岭县| 聂荣县| 永和县| 淮阳县| 安吉县| 咸阳市| 富民县| 温泉县| 会宁县| 乐陵市| 乃东县| 历史| 陕西省| 屯留县| 炎陵县| 上犹县| 潜江市| 南平市| 晋州市| 遵义县| 江西省| 越西县| 凤阳县| 永安市| 务川| 冕宁县| 德州市| 搜索| 疏附县| 黄陵县| 疏勒县| 霍林郭勒市| 保康县| 聂拉木县| 威远县| 丰镇市|