拯救松鼠黨!教你零基礎(chǔ)用python實(shí)現(xiàn)去重文件&釋放空間

-- 系列:日常辦公技巧

-- 作者:alex tang

-- 時(shí)間:01/21-2019

## 一忆绰、業(yè)務(wù)背景

### 1.1背景簡(jiǎn)介

幾年的咨詢工作不僅讓我變得更有經(jīng)驗(yàn)怖竭,更養(yǎng)成了我松鼠黨的習(xí)慣。堆積的資料越來(lái)越多叉谜,而且重復(fù)的文件被放在了不同的目錄旗吁,占用的空間越來(lái)越大,數(shù)量也多得已經(jīng)不太適合人工分辨整理停局。尤其是有的一模一樣的文件被改成不一樣的名字很钓,但實(shí)質(zhì)相同。這種壞現(xiàn)象不僅是電腦董栽,連云盤也是如此码倦。

前兩天整理自己的網(wǎng)盤時(shí)發(fā)現(xiàn)空間已滿,想要使用使用其文件去重功能居然要開通會(huì)員锭碳,最低一檔需付費(fèi)30大洋袁稽。作為科技宅遂決定不讓自己的python吃灰了,自己寫著玩玩擒抛。

本文會(huì)和大家分享如何實(shí)現(xiàn)文件去重推汽,如何掃描自己硬盤和網(wǎng)盤的每一個(gè)目錄。

### 1.2知識(shí)點(diǎn)預(yù)告

本文完成過(guò)程中將使用:

* MD5原理

* 遍歷文件夾

* pathlib模塊的使用

* logging模塊的使用

### 1.3使用環(huán)境

python=3.6.7

pathlib=2.3.2

## 二歧沪、實(shí)現(xiàn)原理

在開始之前歹撒,我先解釋一下這些代碼運(yùn)行的原理——基于文件的完整性( integrity)。如果兩個(gè)文件的內(nèi)容相同诊胞,不管它們文件名相同與否暖夭,它們的MD5值(或者其他哈希算法值)必定是相同的。在這篇文章里撵孤,我使用MD5值來(lái)判斷文件的完整性迈着。

## 三、開發(fā)準(zhǔn)備

linux打開終端邪码,windows使用win+r打開cmd命令行寥假。進(jìn)入code目錄,創(chuàng)建work文件夾霞扬,將其作為工作目錄糕韧。

```python

! cd C:\test\Code&&mkdir work&&cd work

```

? ? 子目錄或文件 work 已經(jīng)存在枫振。


為了實(shí)驗(yàn),我在該文件夾下面放了一個(gè)文件萤彩,并復(fù)制了一下粪滤。這樣兩個(gè)文件的名字就不相同了。

![實(shí)驗(yàn)文件夾](https://github.com/tangshan-risk/cookbook_for_python/blob/master/images/mission001_01.PNG)

安裝所需模塊

```python

! pip install hashlib

! pip install logging

! pip install pathlib

```

## 四雀扶、開發(fā)步驟

### 4.1導(dǎo)入所需package

```python

import os

import hashlib

import logging

import sys

from pathlib import Path

```

### 4.2編寫日志函數(shù)

指定logger輸出格式杖小,明確日志文件名稱和存儲(chǔ)位置,制定日志的最低輸出級(jí)別愚墓。

```python

def logger():

? ? """ 獲取logger"""

? ? logger = logging.getLogger()

? ? if not logger.handlers:

? ? ? ? # 指定logger輸出格式

? ? ? ? formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s')

? ? ? ? # 文件日志

? ? ? ? file_handler = logging.FileHandler("test.log")

? ? ? ? file_handler.setFormatter(formatter)? # 可以通過(guò)setFormatter指定輸出格式

? ? ? ? # 控制臺(tái)日志

? ? ? ? console_handler = logging.StreamHandler(sys.stdout)

? ? ? ? console_handler.formatter = formatter? # 也可以直接給formatter賦值

? ? ? ? # 為logger添加的日志處理器

? ? ? ? logger.addHandler(file_handler)

? ? ? ? logger.addHandler(console_handler)

? ? ? ? # 指定日志的最低輸出級(jí)別予权,默認(rèn)為WARN級(jí)別

? ? ? ? logger.setLevel(logging.INFO)

? ? return logger

```

### 4.3獲得文件的唯一標(biāo)識(shí) - MD5值

假如你要處理的重復(fù)文件有不同的文件名,最簡(jiǎn)單的辦法就是通過(guò)MD5來(lái)確定兩個(gè)文件是不是一樣的浪册。

```python

def md5sum(filename, blocksize=65536):

? ? hash = hashlib.md5()

? ? with open(filename, "rb") as f:

? ? ? ? for block in iter(lambda: f.read(blocksize), b""):

? ? ? ? ? ? hash.update(block)

? ? return hash.hexdigest()

```

這個(gè)方法可以快速獲得一個(gè)文件的MD5值扫腺,blocksize 可以根據(jù)文件大小和CPU性能調(diào)整,一般選擇的值約等于文件的平均大小村象。

### 4.4保存所有文件標(biāo)識(shí)和路徑

接下來(lái)遍歷所有文件笆环,使用MD5作為key,路徑作為value厚者,保存起來(lái)躁劣。

```python

dup = {}

def build_hash_dict(dir_path, pattern='*.xlsx'):


? ? def save(file):

? ? ? ? hash = md5sum(file)

? ? ? ? if hash not in dup.keys():

? ? ? ? ? ? dup[hash] = [file]

? ? ? ? else:

? ? ? ? ? ? dup[hash].append(file)

? ? p = Path(dir_path)

? ? for item in p.glob('**/' + pattern):

? ? ? ? save(str(item))

```

### 4.5處理重復(fù)文件

最后一步非常簡(jiǎn)單,把上一步建立的字典做一個(gè)簡(jiǎn)單的過(guò)濾就能找到重復(fù)文件库菲。

```python

def main():

? ? log = logger()

? ? def get_duplicate():

? ? ? ? return {k: v for k, v in dup.items() if len(v) > 1}

? ? build_hash_dict(work_path)

? ? for hash, files in get_duplicate().items():

? ? ? ? log.info("{}: {}".format(hash, files))

```

如果你想直接刪除冗余文件账忘,而不是自己來(lái)判斷從哪個(gè)文件里面刪除,可在記錄日志后遍歷日志文件列表熙宇,刪除指定文件之外的其他文件內(nèi)容鳖擒。

? ? ? ? #import os

? ? ? ? #[os.remove(file) for file in files[1:]]


### 4.6執(zhí)行函數(shù)代碼

```python

if __name__ == '__main__':

? ? dup = {}

? ? work_path = 'C:\\test\\Code\\work'

? ? main()

```

? ? 2019-01-20 19:37:43,267 INFO? ? : bea3107f0ef871594bedcd992265ade4: ['C:\\test\\Code\\work\\abtForCustomValue-2 - 副本 - 副本.xlsx', 'C:\\test\\Code\\work\\abtForCustomValue-2 - 副本.xlsx']


## 五、代碼獲取

如果您想獲得完整代碼或者封裝好的exe程序奇颠,可以給我留言败去。如果你有建議或者想法放航,也歡迎留言與我溝通烈拒。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市广鳍,隨后出現(xiàn)的幾起案子荆几,更是在濱河造成了極大的恐慌,老刑警劉巖赊时,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吨铸,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡祖秒,警方通過(guò)查閱死者的電腦和手機(jī)诞吱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門舟奠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人房维,你說(shuō)我怎么就攤上這事沼瘫。” “怎么了咙俩?”我有些...
    開封第一講書人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵耿戚,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我阿趁,道長(zhǎng)膜蛔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任脖阵,我火速辦了婚禮皂股,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘独撇。我一直安慰自己屑墨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開白布纷铣。 她就那樣靜靜地躺著卵史,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搜立。 梳的紋絲不亂的頭發(fā)上以躯,一...
    開封第一講書人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音啄踊,去河邊找鬼忧设。 笑死,一個(gè)胖子當(dāng)著我的面吹牛颠通,可吹牛的內(nèi)容都是我干的址晕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼顿锰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谨垃!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起硼控,我...
    開封第一講書人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤刘陶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后牢撼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匙隔,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年熏版,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纷责。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捍掺。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖再膳,靈堂內(nèi)的尸體忽然破棺而出乡小,到底是詐尸還是另有隱情,我是刑警寧澤饵史,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布满钟,位于F島的核電站,受9級(jí)特大地震影響胳喷,放射性物質(zhì)發(fā)生泄漏湃番。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一吭露、第九天 我趴在偏房一處隱蔽的房頂上張望吠撮。 院中可真熱鬧,春花似錦讲竿、人聲如沸泥兰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鞋诗。三九已至,卻和暖如春迈嘹,著一層夾襖步出監(jiān)牢的瞬間削彬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工秀仲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留融痛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓神僵,卻偏偏與公主長(zhǎng)得像雁刷,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子保礼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • From:Python之日志處理(logging模塊) - 云游道士 - 博客園 https://www.cnbl...
    vigny的先生閱讀 2,685評(píng)論 3 5
  • 常用模塊 認(rèn)識(shí)模塊 什么是模塊 什么是模塊氓英? 常見的場(chǎng)景:一個(gè)模塊就是一個(gè)包含了python定義和聲明的文件侯勉,文...
    go以恒閱讀 1,953評(píng)論 0 6
  • logging介紹Python的logging模塊提供了通用的日志系統(tǒng)鹦筹,可以方便第三方模塊或者是應(yīng)用使用铝阐。這個(gè)模塊...
    modingfa閱讀 6,827評(píng)論 0 2
  • 《盟約》 我以永遠(yuǎn)的愛(ài)愛(ài)你我以慈愛(ài)吸引你 聘你永遠(yuǎn)歸我為妻永以慈愛(ài)誠(chéng)實(shí)待你 哦我愿奪得主的心用我注視的眼睛 我的心...
    GRaceChrist閱讀 397評(píng)論 0 1
  • 1.阿雷 Ulord主節(jié)點(diǎn)用來(lái)做什么 2.程文濤 【簡(jiǎn)單對(duì)比】老兵NEO和新星EOS 3.張鵬 「項(xiàng)目分析」EOS...
    Jason葉閱讀 121評(píng)論 0 0