
有沒有辦法在搜尋文件時將雜湊值作為輸入,並將完整的文件列表及其位置作為輸出?
當嘗試找出文件重複項時,這可能會很有幫助。我經常發現自己有一堆文件,我知道我已經將這些文件儲存在某個位置,但我不知道在哪裡。它們本質上是重複的。
例如,我可以在便攜式硬碟上保存一堆文件,並且在桌上型電腦的內部硬碟上保存這些文件的硬拷貝......但我不確定位置!現在,如果檔案未重命名,我可以進行檔案名稱搜尋以嘗試在桌面上找到硬拷貝。然後我可以並排比較它們,如果它們相同,我可以刪除便攜式硬碟上的副本。但是,如果檔案已在任一硬碟上重新命名,則這可能無法運作(取決於新名稱與原始名稱的不同程度)。
如果一個檔案被重命名,但沒有編輯,我可以計算它的雜湊值,例如 SHA1 值為74e7432df4a66f246b5214d60b190b67e2f6ce52
.然後,我希望在搜尋檔案時將此值作為輸入,並讓作業系統在給定目錄或整個檔案系統中搜尋具有此精確 SHA1 雜湊值的文件,並輸出儲存這些檔案的位置的完整清單。
我使用的是 Windows,但我通常有興趣了解如何實現這樣的事情,無論作業系統如何。
答案1
Linux 範例:
hash='74e7432df4a66f246b5214d60b190b67e2f6ce52'
find . -type f -exec sh -c '
sha1sum "$2" | cut -f 1 -d " " | sed "s|^\\\\||" | grep -Eqi "$1"
' find-sh "$hash" {} \; -print
這段程式碼比您想像的更複雜,因為:
- 它的目的是正確處理帶有空格、換行符、反斜線、引號、特殊字元等的檔案名稱(更改
-print
為-print0
以進一步解析它們); - 它旨在接受散列作為正則表達式(與
grep -E
ie相容egrep
),
例如'^00|00$'
,如果文件散列以 ; 開頭或結尾,則將匹配00
;一個更實際的範例是一次搜尋多個雜湊值:('74…|a9…|…|…|…'
為了簡潔,省略號,使用完整雜湊值)。
您可以使用*sum
具有相容介面的其他工具(例如md5sum
)。
答案2
如果您有 PowerShell v.4.0 或更高版本,則可以使用下列命令:
Get-ChildItem _search_location_ -Recurse | Get-FileHash |
Where-Object hash -eq (Get-FileHash _search_file_).hash | Select path
_search_location_
您要在其中搜尋重複項的資料夾或磁碟在哪裡,並且_search_file_
是在某處有重複項的檔案。您可以將此命令放入循環中以搜尋多個文件,或新增| Remove-Item
至行尾以自動刪除重複項。
另請注意,此命令僅適用於小型搜尋資料夾 - 如果您的搜尋位置有數千個檔案(如整個 HDD),則將花費大量時間。
答案3
這是一個有趣的問題。我一直在使用一個名為 fdupes 的工具來完成類似的事情。 Fdupes 將遞歸搜尋目錄並將每個檔案與其他檔案進行比較。首先,它比較大小,如果大小相同,則建立檔案的雜湊值並進行比較,如果雜湊值相同,則實際上逐字節遍歷每個檔案並進行比較。
當 if 找到所有真正相同的檔案時,您可以讓它做幾件事。我讓它刪除重複檔案並在其位置建立硬連結(從而節省硬碟空間),儘管您可以讓它簡單地輸出重複檔案的位置而不對它們執行任何操作。這就是您所詢問的場景。
fdupes 的一些缺點是,據我所知,它僅適用於 Linux,並且由於它將每個檔案與其他檔案進行比較,因此需要相當多的 I/O 和運行時間。它不會“搜尋”每個文件,但會列出具有相同雜湊值的所有文件。
我強烈推薦它,並將其設定為每天在 cron 作業中運行,這樣我就不會出現任何不必要的資料重複(當然,它不包括我的備份)。
答案4
Voidtools Everything 1.5(Alpha)Windows 搜尋工具可選擇為每個檔案新增一列各種雜湊值,例如 CRC-32、CRC-64、MD5、SHA-1、SHA-256。