利用 Linux 查找重複文件

方法一:使用 Find 命令

本部分算是對 find 強大功能的擴展使用方法說明。在 find 的基礎上,我們可與(如 xargs 命令)等其它基本 Linux 命令相結合,即能創造出無限的命令行功能,比如:可以快速查找出 Linux 某個文件夾及其子文件夾中的重複文件列表。要實現這個功能在流程上是比較簡單的,只要查找遍歷出所有文件,再通過命令去比較每個文件的 MD5 就 OK 啦。

聽起來好像比較抽象,其實命令就一條:

find -not -empty -type f -printf "%s\n" | sort -rn | uniq -d | xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | sort | uniq -w32 --all-repeated=separate

方法二:使用 dupeGuru 工具

DupeGuru 是一個跨平臺應用,有 Linux、Windows 和 Mac OS X 版本,它可以通過文件大小、MD5 和文件名等多種標準來幫助用戶找出 Linux 中的重複文件。Ubuntu 用戶可以直接通過添加如下 PPA 源來方式來進行安裝:

sudo add-apt-repository ppa:hsoft/ppa
sudo apt-get update
sudo apt-get install dupeguru*

方法三:使用 Find 命令解析

在工作生活當中,我們很可能會遇到查找重複文件的問題。比如從某遊戲提取的遊戲文本有重複的,我們希望找出所有重複的文本,讓翻譯只翻譯其中一份,而其他的直接替換。那麼這個問題該怎麼做呢?當然方法多種多樣,而且無論那種方法應該都不會太難,但筆者第一次遇到這個問題的時候第一反應是是用 Linux 的 Shell 腳本,所以文本介紹這種方式。

先上代碼:

find -not -empty -type f -printf "%sn" | sort -rn |uniq -d | xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | sort | uniq -w32 --all-repeated=separate | cut -b 36-

大家先 cd 到自己想要查找重複文件的文件夾,然後 copy 上面代碼就可以了,系統會對當前文件夾及子文件夾內的所有文件進行查重。

下面分析一下上面的命令。

首先看第一句:

find -not -empty -type f -printf "%sn"

find 是查找命令;-not -empty 是要尋找非空文件;-type f 是指尋找常規文件;-printf “%sn” 比較具有迷惑性,這裏的 %s 並非 C 語言中的輸出字符串,它實際表示的是文件的大小,單位爲 bytes(不懂就 man,man 一下 find,就可以看到了),n 是換行符。所以這句話的意思是輸出所有非空文件的大小。

通過管道,上面的結果被傳到第二句:

sort -rn

sort 是排序,-n 是指按大小排序,-r 是指從大到小排序(逆序 reverse)。

第三句:

uniq -d

uniq 是把重複的只輸出一次,而 - d 指只輸出重複的部分(如 9 出現了 5 次,那麼就輸出 1 個 9,而 2 只出現了 1 次,並非重複出現的數字,故不輸出)。

第四句:

xargs -I{} -n1 find -type f -size {}c -print0

這一部分分兩部分看,第一部分是 xargs -I{} -n1,xargs 命令將之前的結果轉化爲參數,供後面的 find 調用,其中 - I{}是指把參數寫成 {},而 - n1 是指將之前的結果一個一個輸入給下一個命令(-n8 就是 8 個 8 個輸入給下一句,不寫 - n 就是把之前的結果一股腦的給下一句)。後半部分是 find -type f -size {}c -print0,find 指令我們前面見過,-size{} 是指找出大小爲{}bytes 的文件,而 - print0 則是爲了防止文件名裏帶空格而寫的參數。

第五句:

xargs -0 md5sum

xargs 我們之前說過,是將前面的結果轉化爲輸入,那麼這個 - 0 又是什麼意思?man 一下 xargs,我們看到 - 0 表示讀取參數的時候以 null 爲分隔符讀取,這也不難理解,畢竟 null 的二進制表示就是 00。後面的 md5sum 是指計算輸入的 md5 值。

第六句:sort 是排序,這個我們前面也見過。

第七句:

uniq -w32 --all-repeated=separate

uniq -w32 是指尋找前 32 個字符相同的行,原因在於 md5 值一定是 32 位的,而後面的 --all-repeated=separate 是指將重複的部分放在一類,分類輸出。

第八句:

cut -b 36-

由於我們的結果帶着 md5 值,不是很好看,所以我們截取 md5 值後面的部分,cut 是文本處理函數,這裏 - b 36 - 是指只要每行 36 個字符之後的部分。

我們將上述每個命令用管道鏈接起來,存入 result.txt:

find -not -empty -type f -printf "%sn" | sort -rn |uniq -d | xargs -I{} -n1 find -type f -size {}c -print0 | xargs -0 md5sum | sort | uniq -w32 --all-repeated=separate | cut -b 36- >result.txt

雖然結果很好看,但是有一個問題,這是在 Linux 下很好看,實際上如果有朋友把輸出文件放到 Windows 上,就會發現換行全沒了,這是由於 Linux 下的換行是 n,而 windows 要求 nr,爲了解決這個問題,我們最後執行一條指令,將 n 轉換爲 nr:

cat result.txt | cut -c 36- | tr -s 'n'

推薦關注「Linux 愛好者」,提升 Linux 技能

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/P-j5FvZzyn61t6E24dfaKQ