查找并删除当前目录及其子目录下的所有重复文件

来源:互联网 发布:矩阵非奇异是什么意思 编辑:程序博客网 时间:2024/05/16 14:02
#!/bin/bash
#Function:用于删除当前目录及其子目录下所有重复文件,只保留单个副本
#重复文件指的是那些虽然名字不一样,但内容一模一样的文件
#通过比较md5sum来处理
#Usage:bash removeDuplicateFile.sh
#Date:2016/10
#Author:Jian
#Version:1.0
currentDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

function removeDuplicateFile () {
touch /tmp/duplicateFiles.lst
touch /tmp/fileList.lst
#过滤出当前脚本所在目录下所有普通文件并按大小排序后重定向到文件/tmp/fileList.lst
ls -lS | grep "^-" | awk 'BEGIN{getline} {print $5,$NF}' > /tmp/fileList.lst
#文件行数
line=$(cat /tmp/fileList.lst | wc -l)
#定义关联数组,将上面输出的目录下文件存储到数组中,以便下面处理
declare -A b
for ((i=0; i<$line; i++))
do
  #数组a为普通数组,存储的是文件名
  a[ $i ]=$(cat /tmp/fileList.lst | head -n $[ $i + 1 ] | tail -1 | cut -d" " -f2)
  #数组b为关联数组,存储的是数组a对应文件的大小
  b["${a[ $i ]}"]=$(cat /tmp/fileList.lst | head -n $[ $i + 1 ] | tail -1 | cut -d" " -f1)
done
#下面类似c冒泡方法两两比较是否有文件大小一样的,如果有,则进一步比较md5sum值
for (( j=0; j<$line; j++ ))
do
  for ((k=$[ $j + 1 ]; k<$line; k++))
  do
    if [ ${b["${a[ $j ]}"]} -eq ${b["${a[ $k ]}"]} ]; then
      csum1=`md5sum ${a[ $j ]} | awk 'BEGIN{print $1}'`
      csum2=`md5sum ${a[ $k ]} | awk 'BEGIN{print $1}'`
      if [ $csum1 = $csum2 ]; then
        echo "${a[ $j ]} ${a[ $k ]}" 
      fi
    fi
  done
#将输出的重复文件定向到文件/tmp/duplicateFiles.lst,以便进一步处理
done | cut -d " " -f1 | sort -u > /tmp/duplicateFiles.lst 
if [ $(cat /tmp/duplicateFiles.lst | wc -l) -eq 0 ]; then
  echo "$folder: 0 duplicate files,you don't have to remove any files"
else
echo "$folder:$(cat /tmp/duplicateFiles.lst | wc -l) duplicate files:"
cat /tmp/duplicateFiles.lst 
read -p "Sure to remove the duplicate files?[y/n]" choice
case $choice in
Y|y)
  echo "Removing..."
  #删除重复文件
  cat /tmp/duplicateFiles.lst | xargs -i rm -f {}
  echo "Successfully removed $(cat /tmp/duplicateFiles.lst | wc -l) duplicate files" ;;
N|n)
  echo "You choose to keep these duplicate files" ;;
*)
  echo "Wrong choice" ;;
  esac
fi
}
#遍历当前目录及其子目录
function folderContents(){
for dir in $1/*
do
  if [ -d $dir ]; then
    echo $dir 
    folderContents $dir
  fi
done
}
#将得到的当前目录及子目录结果重定向到文件folderContents.lst
folderContents $currentDir > folderContents.lst
#在各个目录下调用removeDuplicateFile函数
for folder in $currentDir $(cat folderContents.lst)
do
  cd $folder
  removeDuplicateFile
done
#删除临时文件
cd $currentDir
rm -rf folderContents.lst
cd /tmp
rm -rf duplicateFiles.lst 
rm -rf fileList.lst
exit 0
0 0