#!/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