--- /dev/null
+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)
+}