本文目录导读:

我来介绍几种在Shell脚本中查找和去重重复文件的方法:
基于MD5校验的方法
#!/bin/bash
# 方法1:查找重复文件并显示
find . -type f -exec md5sum {} \; | sort | uniq -d -w 32
# 方法2:显示重复文件的分组
find . -type f -exec md5sum {} \; | sort | awk '{
if (seen[$1]) {
print "Duplicate:", $2
} else {
seen[$1] = $2
}
}'
# 方法3:完整的去重脚本
find_duplicates() {
local search_dir="${1:-.}"
echo "正在查找重复文件..."
find "$search_dir" -type f -exec md5sum {} \; |
sort |
awk '{
if (seen[$1]) {
print "DUPLICATE: " $2
duplicates[$1]++
} else {
seen[$1] = $2
}
}'
echo "统计重复文件数量..."
awk '{print $1}' | sort | uniq -c | sort -rn
}
保留一个副本删除其余
#!/bin/bash
# 保留第一个文件,删除其他重复文件
dedup_keep_first() {
local directory="${1:-.}"
declare -A file_hashes
find "$directory" -type f | while read -r file; do
hash=$(md5sum "$file" | cut -d' ' -f1)
if [[ -n "${file_hashes[$hash]}" ]]; then
echo "删除重复文件: $file"
rm "$file"
else
file_hashes[$hash]="$file"
fi
done
}
# 交互式去重(询问是否删除)
dedup_interactive() {
find . -type f -exec md5sum {} \; | sort | awk '
NR == 1 { first=$2; hash=$1 }
NR > 1 {
if ($1 == hash) {
printf "保留: %s\n删除: %s [y/N] ", first, $2
getline answer < "/dev/tty"
if (answer == "y" || answer == "Y") {
system("rm \"" $2 "\"")
print "已删除"
} else {
print "保留"
first=$2
}
} else {
first=$2
hash=$1
}
}'
}
使用shasum(更准确的校验)
#!/bin/bash
# 使用SHA256校验
find_duplicates_sha256() {
find . -type f -exec sha256sum {} \; | sort | uniq -d -w 64 | while read -r hash file; do
echo "重复文件: $file"
done
}
# 查找并移动到回收站
dedup_to_trash() {
local trash_dir="${HOME}/.trash"
mkdir -p "$trash_dir"
find . -type f -exec sha256sum {} \; | sort | awk '
{
if (seen[$1]) {
dest="'"$trash_dir"'" "/" $2
mkdir -p "$(dirname "$dest")"
system("mv \"" $2 "\" \"" dest "\"")
print "移动到回收站: " $2
} else {
seen[$1] = $2
}
}'
}
高级功能脚本
#!/bin/bash
# 完整的去重工具
dedup_tool() {
local search_dir="${1:-.}"
local action="${2:-list}" # list, delete, move, hardlink
local hash_cmd="${3:-md5sum}"
local temp_file=$(mktemp)
echo "扫描目录: $search_dir"
echo "使用算法: $hash_cmd"
echo "操作模式: $action"
# 生成文件哈希列表
find "$search_dir" -type f -exec "$hash_cmd" {} \; > "$temp_file"
# 根据模式处理
case "$action" in
list)
cat "$temp_file" | sort | awk '
NR == 1 { first=$2; hash=$1 }
NR > 1 {
if ($1 == hash) {
print first
print $2
} else {
first=$2
hash=$1
}
}' | sort -u
;;
delete)
cat "$temp_file" | sort | awk '
{
if (seen[$1]) {
print "删除: " $2
system("rm \"" $2 "\"")
} else {
seen[$1] = $2
}
}'
;;
move)
local backup_dir="${search_dir}/duplicates_backup"
mkdir -p "$backup_dir"
cat "$temp_file" | sort | awk -v backup="$backup_dir" '
{
if (seen[$1]) {
dir=backup "/" $2
system("mkdir -p \"$(dirname \"" dir "\")\"")
system("mv \"" $2 "\" \"" dir "\"")
print "移动: " $2
} else {
seen[$1] = $2
}
}'
;;
hardlink)
# 使用硬链接节省空间
cat "$temp_file" | sort | awk '
{
if (seen[$1]) {
system("ln -f \"" seen[$1] "\" \"" $2 "\"")
print "硬链接: " $2 " -> " seen[$1]
} else {
seen[$1] = $2
}
}'
;;
esac
rm -f "$temp_file"
}
# 使用方法
# dedup_tool "/path/to/dir" "list" "sha256sum"
# dedup_tool "/path/to/dir" "delete" "md5sum"
# dedup_tool "/path/to/dir" "hardlink" "sha1sum"
性能优化版本(适合大文件)
#!/bin/bash
# 快速去重(先按文件大小过滤)
dedup_fast() {
local directory="${1:-.}"
echo "步骤1: 按文件大小分组..."
find "$directory" -type f -exec stat -f"%z %N" {} \; | sort -n | awk '
{
if (size != $1) {
size=$1
files=$2
} else {
print files
print $2
}
}' | while read -r file1 && read -r file2; do
# 只对大小相同的文件进行哈希比较
if [ -f "$file1" ] && [ -f "$file2" ]; then
if cmp -s "$file1" "$file2"; then
echo "重复文件: $file1 和 $file2"
fi
fi
done
}
统计报告版本
#!/bin/bash
# 生成重复文件报告
report_duplicates() {
local directory="${1:-.}"
local report_file="duplicates_report_$(date +%Y%m%d).txt"
{
echo "重复文件报告"
echo "生成时间: $(date)"
echo "扫描目录: $directory"
echo "========================================"
echo ""
find "$directory" -type f -exec sha256sum {} \; | sort | awk '
{
if (seen[$1]) {
if (!header_printed[$1]) {
print "哈希: " $1
print " 原始: " seen[$1]
header_printed[$1] = 1
}
print " 重复: " $2
count[$1]++
} else {
seen[$1] = $2
}
}
END {
print ""
print "统计信息:"
for (hash in count) {
print " " count[hash] "个重复文件 (哈希: " substr(hash,1,8) "...)"
}
}'
} > "$report_file"
echo "报告已保存到: $report_file"
wc -l "$report_file"
}
使用建议
- 先测试:在正式删除前先用
list模式查看结果 - 备份重要文件:使用
move模式移动重复文件 - 大文件处理:先按大小过滤,再比较校验码
- 软链接保留:如需保留软链接,使用
-L参数 - 空格处理:确保文件名含空格时正确引用
- 权限问题:可能需要
sudo权限访问某些文件
这些脚本可以根据实际需求进行调整和组合使用。
版权声明: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直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播