本文目录导读:

Python 脚本(推荐)
基础版本(MD5校验)
import os
import hashlib
from pathlib import Path
def get_file_hash(filepath):
"""计算文件MD5哈希值"""
hash_md5 = hashlib.md5()
with open(filepath, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def find_duplicates(directory):
"""查找重复文件"""
files = {}
duplicates = []
for filepath in Path(directory).rglob("*"):
if filepath.is_file():
try:
file_hash = get_file_hash(filepath)
file_size = filepath.stat().st_size
key = (file_hash, file_size)
if key in files:
duplicates.append((files[key], filepath))
else:
files[key] = filepath
except Exception as e:
print(f"Error processing {filepath}: {e}")
return duplicates
def clean_duplicates(duplicates, delete=False):
"""清理重复文件"""
print(f"Found {len(duplicates)} duplicate groups:")
for original, duplicate in duplicates:
print(f" Original: {original}")
print(f" Duplicate: {duplicate}")
print("-" * 50)
if delete:
try:
os.remove(duplicate)
print(f" Deleted: {duplicate}")
except Exception as e:
print(f" Error deleting: {e}")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Find and clean duplicate files")
parser.add_argument("directory", help="Directory to scan")
parser.add_argument("--delete", action="store_true", help="Actually delete duplicates")
parser.add_argument("--dry-run", action="store_true", help="Show what would be deleted")
args = parser.parse_args()
duplicates = find_duplicates(args.directory)
clean_duplicates(duplicates, delete=args.delete or args.dry_run)
增强版本(多线程+进度条)
import os
import hashlib
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
import tqdm
def get_file_hash(filepath):
"""带进度显示的文件哈希计算"""
hash_md5 = hashlib.md5()
file_size = filepath.stat().st_size
with open(filepath, "rb") as f:
with tqdm.tqdm(total=file_size, unit='B', unit_scale=True,
desc=filepath.name, leave=False) as pbar:
for chunk in iter(lambda: f.read(8192), b""):
hash_md5.update(chunk)
pbar.update(len(chunk))
return hash_md5.hexdigest()
def find_duplicates_parallel(directory, workers=4):
"""并行查找重复文件"""
files = []
for filepath in Path(directory).rglob("*"):
if filepath.is_file():
files.append(filepath)
print(f"Scanning {len(files)} files...")
with ThreadPoolExecutor(max_workers=workers) as executor:
file_hashes = list(tqdm(
executor.map(get_file_hash, files),
total=len(files),
desc="Calculating hashes"
))
# 按文件大小分组,先快速比较大小
size_groups = {}
for filepath, file_hash in zip(files, file_hashes):
size = filepath.stat().st_size
if size not in size_groups:
size_groups[size] = []
size_groups[size].append((file_hash, filepath))
# 找出重复文件
duplicates = []
for size, group in size_groups.items():
if len(group) > 1:
hash_groups = {}
for file_hash, filepath in group:
if file_hash not in hash_groups:
hash_groups[file_hash] = []
hash_groups[file_hash].append(filepath)
for hash_val, file_list in hash_groups.items():
if len(file_list) > 1:
duplicates.append(file_list)
return duplicates
Bash 脚本(Linux系统)
#!/bin/bash
# 重复文件清理脚本
# 使用方法: ./dedup.sh [目录路径]
# 设置颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'
find_duplicates() {
local search_dir="${1:-.}"
echo -e "${GREEN}扫描目录: $search_dir${NC}"
# 按文件大小分组
find "$search_dir" -type f -exec stat -c '%s %n' {} \; | \
sort -n | \
awk '{
if ($1 == size) {
print $0
}
size = $1
}' > /tmp/same_size.txt
# 计算MD5并找出重复
while IFS= read -r line; do
size=$(echo "$line" | cut -d' ' -f1)
file=$(echo "$line" | cut -d' ' -f2-)
md5=$(md5sum "$file" | cut -d' ' -f1)
echo "$size $md5 $file"
done < /tmp/same_size.txt | \
sort -k1,2 | \
awk '{
if ($1 == size && $2 == md5) {
print $0
}
size = $1
md5 = $2
}' > /tmp/duplicates.txt
echo -e "${RED}找到重复文件:${NC}"
cat /tmp/duplicates.txt
# 询问是否删除
read -p "是否删除重复文件? (y/n): " answer
if [[ "$answer" == "y" ]]; then
while IFS= read -r line; do
file=$(echo "$line" | cut -d' ' -f3-)
echo "删除: $file"
# rm "$file" # 取消注释以实际删除
done < /tmp/duplicates.txt
fi
# 清理临时文件
rm -f /tmp/same_size.txt /tmp/duplicates.txt
}
# 主程序
main() {
local dir="${1:-.}"
if [ ! -d "$dir" ]; then
echo "错误: 目录不存在"
exit 1
fi
find_duplicates "$dir"
}
main "$@"
PowerShell 脚本(Windows系统)
# 重复文件清理脚本
# 使用方法: .\dedup.ps1 -Path "C:\MyFiles"
param(
[Parameter(Mandatory=$true)]
[string]$Path,
[switch]$Delete,
[switch]$DryRun
)
function Get-FileHash {
param([string]$FilePath)
try {
$hash = Get-FileHash -Path $FilePath -Algorithm MD5
return $hash.Hash
}
catch {
Write-Warning "无法读取文件: $FilePath"
return $null
}
}
function Find-Duplicates {
param([string]$Directory)
$files = Get-ChildItem -Path $Directory -Recurse -File
$groups = @{}
foreach ($file in $files) {
$key = "$($file.Length)|$($file.Name)" # 先用大小和文件名分组
if (-not $groups.ContainsKey($key)) {
$groups[$key] = @()
}
$groups[$key] += $file
}
$duplicates = @()
foreach ($group in $groups.Values) {
if ($group.Count -gt 1) {
# 进一步用哈希值确认
$hashGroups = @{}
foreach ($file in $group) {
$hash = Get-FileHash -FilePath $file.FullName
if ($hash) {
if (-not $hashGroups.ContainsKey($hash)) {
$hashGroups[$hash] = @()
}
$hashGroups[$hash] += $file
}
}
foreach ($hashGroup in $hashGroups.Values) {
if ($hashGroup.Count -gt 1) {
$duplicates += $hashGroup
}
}
}
}
return $duplicates
}
function Clean-Duplicates {
param(
[array]$Duplicates,
[bool]$Delete = $false,
[bool]$DryRun = $true
)
Write-Host "找到 $($Duplicates.Count) 个重复文件" -ForegroundColor Yellow
# 保留第一个,删除其余的
for ($i = 0; $i -lt $Duplicates.Count; $i += 2) {
$original = $Duplicates[$i]
$duplicate = $Duplicates[$i + 1]
Write-Host "原始文件: $($original.FullName)" -ForegroundColor Green
Write-Host "重复文件: $($duplicate.FullName)" -ForegroundColor Red
if ($Delete -and -not $DryRun) {
try {
Remove-Item -Path $duplicate.FullName -Force
Write-Host "已删除" -ForegroundColor Green
}
catch {
Write-Host "删除失败: $_" -ForegroundColor Red
}
}
else {
Write-Host "预览模式,未实际删除" -ForegroundColor Yellow
}
}
}
# 主程序
Write-Host "开始扫描: $Path" -ForegroundColor Cyan
$duplicates = Find-Duplicates -Directory $Path
Clean-Duplicates -Duplicates $duplicates -Delete $Delete.IsPresent -DryRun $DryRun.IsPresent
Write-Host "完成!" -ForegroundColor Cyan
使用建议
安全第一
- 始终先用
--dry-run或预览模式查看结果 - 建议先复制到测试目录再运行
- 重要文件先备份
优化技巧
- 先按大小过滤:相同大小的文件才可能是重复
- 分批处理:大文件建议分批处理
- 使用增量哈希:先计算部分哈希,匹配再计算完整哈希
安装依赖(Python版本)
pip install tqdm # 进度条
选择适合你系统的脚本,首先在测试目录中运行,确保一切正常后再应用于重要文件。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播