3

[Golang] Split Contents of a Directory into Multiple Sub Directories

 2 years ago
source link: http://siongui.github.io/2018/04/03/go-split-content-of-a-directory-into-multiple-sub-directory/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

[Golang] Split Contents of a Directory into Multiple Sub Directories

April 03, 2018

Split contents of a directory into multiple sub-directory in Go. For example, if you have a directory with 1,000 files, you split them into 4 sub-directories, each with 300, 300, 300, 100 files inside. You can specify the maximum number of files in each subdirectories.

You can also do this via shell command. See [2].

package main

import (
      "flag"
      "fmt"
      "io/ioutil"
      "os"
      "path"
      "strconv"
)

var maxFilesPerDir = 1500

func getTargetDir(groupCount int, srcDir string) string {
      return path.Join(srcDir, "dir"+strconv.Itoa(groupCount))
}

func createDirIfNotExist(dir string) {
      if _, err := os.Stat(dir); os.IsNotExist(err) {
              err = os.MkdirAll(dir, 0755)
              if err != nil {
                      panic(err)
              }
      }
}

func moveFilesToDir(filesGroup [][]os.FileInfo, srcDir string) {
      for i, group := range filesGroup {
              targetDir := getTargetDir(i, srcDir)
              createDirIfNotExist(targetDir)
              for _, file := range group {
                      filepath := path.Join(srcDir, file.Name())
                      targetFilepath := path.Join(targetDir, file.Name())
                      fmt.Println("move", filepath, "to", targetFilepath)
                      os.Rename(filepath, targetFilepath)
              }
      }
}

func makeFilesGroup(srcDir string) [][]os.FileInfo {
      files, err := ioutil.ReadDir(srcDir)
      if err != nil {
              panic(err)
      }

      count := 0
      var filesGroup [][]os.FileInfo
      filesGroup = append(filesGroup, []os.FileInfo{})
      groupCount := 0
      for _, file := range files {
              if file.Mode().IsRegular() {
                      filesGroup[groupCount] = append(filesGroup[groupCount], file)
                      count++
                      if count == maxFilesPerDir {
                              count = 0
                              filesGroup = append(filesGroup, []os.FileInfo{})
                              groupCount++
                      }
              }
      }

      return filesGroup
}

func main() {
      srcDir := flag.String("src", "", "source dir to split")
      max := flag.Int("max", 1500, "max number of files in split dir")
      flag.Parse()

      maxFilesPerDir = *max
      filesGroup := makeFilesGroup(*srcDir)
      moveFilesToDir(filesGroup, *srcDir)
}

Usage: max means the number of max number of files in sub directory, and src means the path to the directory to split

$ go run splitdir.go -max=500 -src=/path/to/dir/

Tested on: Ubuntu Linux 17.10, Go 1.10.1


References:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK