跨平台可定制查找重复文件工具

自己最真实的需求,从大学时期产生的各种文件一直被我存着,重复文件就再所难免。已经存在几款查找重复工具可以满足我的基本需求,但是我的个别需求却无法满足,不得不让我重新造轮子,现在将我实现的小工具分享给大家。

我认为具有如下优点

  • 跨平台(支持 Windows, Linux, Mac)
  • 可定制(若你会点编程可轻松扩展你的需求)

工具特性

  • 跳过 . 开头目录,但会打印出来这些路径
  • 跳过大小为 0 的文件
  • 打印后缀为 rar zip iso tar gz 的文件,主要是担心解压后会产生重复文件,提醒你关注一下
  • 通过比对文件内容 md5 值判定是否重复,坚信内容相同文件就相同
  • 多个相同文件一起打印,相同文件有序打印,整体有序打印,便于查看

下载
find repetition

备注
####point#### 标识开始打印 . 开头目录
####compress#### 标识开始打印后缀为 rar zip iso tar gz 的文件

使用(均在各系统命令行下执行,在工具执行完成后打开 output.txt 文件查看打印)

Windows
windows.exe -path=F:\panshiqu 1>output.txt 2>&1

Linux
./linux -path=/home/panshiqu > output.txt

Mac
./mac -path=/home/panshiqu > output.txt

提醒
你可在分析打印后大致推测出那两个文件夹可能相同,这里推荐你使用 Beyond Compare 比对两个庞大的文件夹是否相同,记得 会话 => 会话设置 => 比较 取消比较时间戳,勾选比较内容

源码

package main

import (
	"bytes"
	"crypto/md5"
	"flag"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"sort"
	"strings"
)

var kv map[string][]string

var point []string

var compress []string

var path = flag.String("path", "", "")

// FileList 文件列表
func FileList(path string) {
	if err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
		if info == nil {
			fmt.Println("info", err)
			return err
		}

		if info.IsDir() {
			if strings.HasPrefix(info.Name(), ".") {
				point = append(point, path)
				return filepath.SkipDir
			}

			return nil
		}

		if info.Size() == 0 {
			return nil
		}

		lowerName := strings.ToLower(info.Name())
		if strings.HasSuffix(lowerName, ".rar") ||
			strings.HasSuffix(lowerName, ".zip") ||
			strings.HasSuffix(lowerName, ".iso") ||
			strings.HasSuffix(lowerName, ".tar") ||
			strings.HasSuffix(lowerName, ".gz") {
			compress = append(compress, path)
		}

		f, err := os.Open(path)
		if err != nil {
			fmt.Println("Open", err)
			return err
		}

		defer f.Close()

		md5hash := md5.New()
		if _, err := io.Copy(md5hash, f); err != nil {
			fmt.Println("Copy", err)
			return err
		}

		key := fmt.Sprintf("%x", md5hash.Sum(nil))

		kv[key] = append(kv[key], path)

		return nil
	}); err != nil {
		fmt.Println("FileList", err)
	}
}

// SortOne 一维排序
type SortOne []string

func (s SortOne) Len() int {
	return len(s)
}
func (s SortOne) Less(i, j int) bool {
	return bytes.Compare([]byte(s[i]), []byte(s[j])) < 0
}
func (s SortOne) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

// SortTwo 二维排序
type SortTwo [][]string

func (s SortTwo) Len() int {
	return len(s)
}
func (s SortTwo) Less(i, j int) bool {
	return bytes.Compare([]byte(s[i][0]), []byte(s[j][0])) < 0
}
func (s SortTwo) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func main() {
	flag.Parse()

	kv = make(map[string][]string)

	FileList(*path)

	var tmp [][]string
	for _, v := range kv {
		if len(v) == 1 {
			continue
		}

		tmp = append(tmp, v)
	}

	for i := 0; i < len(tmp); i++ {
		sort.Sort(SortOne(tmp[i]))
	}

	sort.Sort(SortTwo(tmp))

	for _, v := range tmp {
		for _, vv := range v {
			fmt.Println(vv)
		}

		fmt.Println()
	}

	fmt.Println("####point####")
	for _, v := range point {
		fmt.Println(v)
	}

	fmt.Println("####compress####")
	for _, v := range compress {
		fmt.Println(v)
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值