Add directory_merge.go
authorColin Patrick Mccabe <cmccabe@alumni.cmu.edu>
Sun, 21 Aug 2016 22:17:45 +0000 (15:17 -0700)
committerColin Patrick Mccabe <cmccabe@alumni.cmu.edu>
Sun, 21 Aug 2016 22:17:45 +0000 (15:17 -0700)
.gitignore
directory_merge.go [new file with mode: 0644]

index 6d9e56f..5c2abdc 100644 (file)
@@ -13,6 +13,7 @@ show_default_sockopts
 print-code-points
 hexconv
 msgpack-translate
+directory_merge
 
 #
 # Normal rules
diff --git a/directory_merge.go b/directory_merge.go
new file mode 100644 (file)
index 0000000..31af6fe
--- /dev/null
@@ -0,0 +1,95 @@
+package main
+
+import (
+       "bufio"
+       "errors"
+       "fmt"
+       "io/ioutil"
+       "math"
+       "os"
+       "strings"
+)
+
+func usage(retval int) {
+       fmt.Printf("directory_merge: moves files from multiple directories " +
+               "into a single directory\n");
+       fmt.Printf("usage: directory_merge [destination_directory] " +
+               "[source_dir 1] ... [source_dir N]\n")
+       os.Exit(retval)
+}
+
+type RenamePlan struct {
+       src string
+       dstIdx uint64
+}
+
+func (plan *RenamePlan) DstToString(numDigits int) string {
+       return fmt.Sprintf("%0" + fmt.Sprintf("%d", numDigits) + "d", plan.dstIdx);
+}
+
+func (plan *RenamePlan) String(dstDir string, numDigits int) string {
+       return plan.src + " -> " + dstDir + "/" + plan.DstToString(numDigits);
+}
+
+func (plan *RenamePlan) Execute(dstDir string, numDigits int) error {
+       dstFile := dstDir + "/" + plan.DstToString(numDigits)
+       fmt.Printf("Renaming %s to %s.\n", plan.src, dstFile)
+       err := os.Rename(plan.src, dstFile)
+       if err != nil {
+               return errors.New(fmt.Sprintf("Failed to rename %s to %s: %v\n",
+                       plan.src, dstFile, err.Error()))
+       }
+       return nil
+}
+
+func main() {
+       if (len(os.Args) < 3) {
+               usage(1)
+       }
+       dstDir := os.Args[1]
+       srcDirs := os.Args[2:]
+       renamePlans := make([]*RenamePlan, 0)
+       var dstIdx uint64
+       for srcDirIdx := range srcDirs {
+               // ioutil.ReadDir alphabetizes what it returns
+               srcDir := srcDirs[srcDirIdx]
+               srcs, err := ioutil.ReadDir(srcDir)
+               if err != nil {
+                       panic(fmt.Sprintf("Error reading directory %s: %s", srcDir, err))
+               }
+               for srcIdx := range srcs {
+                       srcPath := srcDir + "/" + srcs[srcIdx].Name()
+                       dstIdx++
+                       renamePlan := &RenamePlan {
+                               src: srcPath,
+                               dstIdx: dstIdx,
+                       }
+                       renamePlans = append(renamePlans, renamePlan)
+               }
+       }
+       numDigits := int(math.Ceil(math.Log10(float64(dstIdx))))
+       for renamePlanIdx := range renamePlans {
+               fmt.Printf("%s\n", renamePlans[renamePlanIdx].
+                                                               String(dstDir, numDigits));
+       }
+       reader := bufio.NewReader(os.Stdin)
+       for {
+               fmt.Printf("Execute? (y/n):\n")
+               text, _ := reader.ReadString('\n')
+               text = strings.TrimSpace(text)
+               if text == "y" {
+                       break
+               }
+               if text == "n" {
+                       fmt.Printf("Aborting.\n");
+                       os.Exit(0)
+               }
+       }
+       for renamePlanIdx := range renamePlans {
+               err := renamePlans[renamePlanIdx].Execute(dstDir, numDigits);
+               if err != nil {
+                       panic(err)
+               }
+       }
+       os.Exit(0)
+}