diff options
| author | Mitch Riedstra <mitch@riedstra.us> | 2020-09-27 17:53:15 -0400 |
|---|---|---|
| committer | Mitch Riedstra <mitch@riedstra.us> | 2020-09-27 17:53:15 -0400 |
| commit | 0b830cc8bb7fde0bbf9514b8ae607084188c5c8e (patch) | |
| tree | e9602d6da0a58a549911b83755c3bac26856022c | |
| download | deduplicator-0b830cc8bb7fde0bbf9514b8ae607084188c5c8e.tar.gz deduplicator-0b830cc8bb7fde0bbf9514b8ae607084188c5c8e.tar.xz | |
initial
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | dedup.go | 100 |
2 files changed, 102 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0aa6c13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +deduplicator +testdir diff --git a/dedup.go b/dedup.go new file mode 100644 index 0000000..a6b4549 --- /dev/null +++ b/dedup.go @@ -0,0 +1,100 @@ +package main + +import ( + "crypto/sha256" + "flag" + "fmt" + "io" + "os" + "path/filepath" + "strings" +) + +// sha256Sum Takes an io.Reader and computes the checksum returning it as a +// formatted string and an error if any +func sha256Sum(rdr io.Reader) (string, error) { + h := sha256.New() + if _, err := io.Copy(h, rdr); err != nil { + return "", err + } + + return fmt.Sprintf("%X", h.Sum(nil)), nil +} + +// Takes a filepath and returns the sha256sum and an error if any +func getChecksum(fileName string) (string, error) { + fh, err := os.Open(fileName) + if err != nil { + return "", err + } + defer fh.Close() + + return sha256Sum(fh) +} + +func main() { + fl := flag.NewFlagSet("deduplicator", flag.ExitOnError) + + path := fl.String("path", ".", "Path to deduplicate files in") + all := fl.Bool("a", false, "Scan hidden files as well") + script := fl.Bool("s", false, "Output format sutiable for scripts") + + _ = fl.Parse(os.Args[1:]) + + // checksum -> filepaths + checksums := make(map[string][]string) + + err := filepath.Walk(*path, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !*all { + if strings.Contains(path, "/.") { + return nil + } + } + + if info.IsDir() { + return nil + } + + sum, err := getChecksum(path) + if err != nil { + return err + } + + if _, ok := checksums[sum]; !ok { + checksums[sum] = []string{path} + } else { + checksums[sum] = append( + checksums[sum], + path) + } + + return nil + }) + + if err != nil { + fmt.Fprintln(os.Stderr, err) + } + + for sum, list := range checksums { + if len(list) == 1 { + continue + } + + switch { + case *script: + for _, path := range list { + fmt.Printf("%s::%s\n", sum, path) + } + default: + fmt.Println(sum) + for _, path := range list { + fmt.Println("\t" + path) + } + } + } + +} |
