Linux系统查找同名文件管理删除操作Shell脚本
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # 无颜色
# 显示帮助信息
show_help() {
echo -e "${BLUE}同名文件查找和管理工具${NC}"
echo "用法: $0 [选项] [目录]"
echo "选项:"
echo " -h, --help 显示此帮助信息"
echo " -r, --recursive递归查找子目录"
echo " -d, --delete 直接进入删除模式"
echo " -s, --size 显示文件大小"
echo " -t, --time 显示修改时间"
echo ""
echo "示例:"
echo " $0 ~/Downloads # 查找指定目录"
echo " $0 -r ~/Documents # 递归查找"
echo " $0 -s -t . # 显示详细信息"
}
# 查找同名文件
find_duplicate_names() {
local target_dir="$1"
local recursive="$2"
echo -e "${BLUE}正在扫描目录: $target_dir${NC}"
echo -e "${BLUE}================================${NC}"
# 使用不同的find命令根据递归选项
if [ "$recursive" = true ]; then
find_cmd="find \"$target_dir\" -type f"
else
find_cmd="find \"$target_dir\" -maxdepth 1 -type f"
fi
# 查找所有文件并统计同名文件
eval $find_cmd | while IFS= read -r file; do
filename=$(basename "$file")
echo "$filename|$file"
done | sort | uniq -c | grep -v '^ *1 ' | while read count line; do
filename=$(echo "$line" | cut -d'|' -f1)
filepath=$(echo "$line" | cut -d'|' -f2)
# 统计同名文件数量
actual_count=$(eval $find_cmd -name "$filename" | wc -l)
if [ $actual_count -gt 1 ]; then
echo -e "${YELLOW}\n发现 $actual_count 个同名文件: $filename${NC}"
# 显示每个文件的信息
file_num=1
eval $find_cmd -name "$filename" | while IFS= read -r duplicate; do
if [ "$show_size" = true ]; then
size=$(du -h "$duplicate" | cut -f1)
size_info="大小: $size"
else
size_info=""
fi
if [ "$show_time" = true ]; then
mtime=$(stat -c "%y" "$duplicate" | cut -d'.' -f1)
time_info="修改时间: $mtime"
else
time_info=""
fi
echo -e "${GREEN}[$file_num] ${duplicate}${NC}"
if [ -n "$size_info" ] || [ -n "$time_info" ]; then
echo " $size_info $time_info"
fi
file_num=$((file_num + 1))
done
fi
done
}
# 删除文件处理
handle_deletion() {
local target_dir="$1"
local recursive="$2"
echo -e "${RED}\n警告: 删除模式${NC}"
echo -e "${RED}================================${NC}"
# 查找所有文件
if [ "$recursive" = true ]; then
find_cmd="find \"$target_dir\" -type f"
else
find_cmd="find \"$target_dir\" -maxdepth 1 -type f"
fi
# 收集所有文件名
eval $find_cmd | while IFS= read -r file; do
filename=$(basename "$file")
echo "$filename|$file"
done | sort | uniq -c | grep -v '^ *1 ' | while read count line; do
filename=$(echo "$line" | cut -d'|' -f1)
filepath=$(echo "$line" | cut -d'|' -f2)
# 统计同名文件
duplicates=($(eval $find_cmd -name "$filename"))
actual_count=${#duplicates[@]}
if [ $actual_count -gt 1 ]; then
echo -e "${YELLOW}\n处理文件: $filename (共 $actual_count 个)${NC}"
# 显示文件列表
for i in "${!duplicates[@]}"; do
echo -e "${GREEN}[$((i+1))] ${duplicates[i]}${NC}"
done
# 获取用户选择
echo -e "${BLUE}请选择操作:${NC}"
echo " [0] 跳过此文件"
echo " [1-$actual_count] 删除对应文件"
echo " [a] 删除所有同名文件"
echo " [k] 保留所有并继续"
read -p "请输入选择: " choice
case $choice in
0)
echo "跳过 $filename"
;;
a)
echo -e "${RED}删除所有 $actual_count 个文件${NC}"
for file in "${duplicates[@]}"; do
rm -v "$file"
done
;;
k)
echo "保留所有文件"
;;
[1-9]*)
if [[ $choice =~ ^[0-9]+$ ]] && [ $choice -ge 1 ] && [ $choice -le $actual_count ]; then
file_to_delete="${duplicates[$((choice-1))]}"
echo -e "${RED}删除文件: $file_to_delete${NC}"
rm -v "$file_to_delete"
else
echo "无效的选择"
fi
;;
*)
echo "无效的输入"
;;
esac
fi
done
}
# 主函数
main() {
# 默认值
target_dir="."
recursive=false
delete_mode=false
show_size=false
show_time=false
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-r|--recursive)
recursive=true
shift
;;
-d|--delete)
delete_mode=true
shift
;;
-s|--size)
show_size=true
shift
;;
-t|--time)
show_time=true
shift
;;
-*)
echo -e "${RED}未知选项: $1${NC}"
show_help
exit 1
;;
*)
target_dir="$1"
shift
;;
esac
done
# 检查目录是否存在
if [ ! -d "$target_dir" ]; then
echo -e "${RED}错误: 目录不存在: $target_dir${NC}"
exit 1
fi
# 检查是否安装必要工具
if ! command -v find &> /dev/null; then
echo -e "${RED}错误: find 命令未找到${NC}"
exit 1
fi
# 执行相应模式
if [ "$delete_mode" = true ]; then
handle_deletion "$target_dir" "$recursive"
else
find_duplicate_names "$target_dir" "$recursive"
# 询问是否进入删除模式
echo -e "\n${BLUE}================================${NC}"
read -p "是否要进入删除模式?(y/N): " answer
if [[ $answer =~ ^[Yy]$ ]]; then
handle_deletion "$target_dir" "$recursive"
fi
fi
echo -e "${GREEN}\n操作完成!${NC}"
}
# 执行主函数
main "$@"
使用方法
1.保存脚本
# 将脚本保存为 find_duplicates.sh
chmod +x find_duplicates.sh
2.基本用法
# 在当前目录查找同名文件
./find_duplicates.sh
# 在指定目录查找
./find_duplicates.sh ~/Downloads
# 递归查找
./find_duplicates.sh -r ~/Documents
显示详细信息
# 显示文件大小和修改时间
./find_duplicates.sh -s -t .
# 直接进入删除模式
./find_duplicates.sh -d ~/Downloads