查找並刪除當前目錄及其子目錄下的所有重複文件

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



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章