Skip to content

Instantly share code, notes, and snippets.

@hhsprings
Last active February 27, 2022 06:37
Show Gist options
  • Save hhsprings/e3d948d707e3d3e526e43783f382f282 to your computer and use it in GitHub Desktop.
Save hhsprings/e3d948d707e3d3e526e43783f382f282 to your computer and use it in GitHub Desktop.
remove empty directories, written by Golang
package main
import (
"os"
"log"
"sort"
"strings"
"path/filepath"
)
type pendDir struct {
path string
depth int
}
func collectTargDirs(root string, alldirs *[]pendDir) {
ents, err := os.ReadDir(root)
if err != nil {
log.Print(err)
return
}
for _, ent := range ents {
path := filepath.ToSlash(
filepath.Join(root, ent.Name()))
if ent.IsDir() {
/*
* "Os.Remove" for a directory fails because the
* directory is not empty or for some other reason.
* Here, the latter case can be postponed and only
* the report of successful deletion of the empty
* directory is sufficient.
*/
rmerr := os.Remove(path)
if rmerr == nil {
log.Printf("removed empty dir: %s\n", path)
continue
}
*alldirs = append(
*alldirs,
pendDir{path: path, depth: len(strings.Split(path, "/"))})
collectTargDirs(path, alldirs)
}
}
}
func RmdirHier(roots []string) {
var alldirs []pendDir
for _, root := range roots {
collectTargDirs(root, &alldirs)
}
sort.Slice(alldirs, func(i, j int) bool {
lhs := alldirs[i]
rhs := alldirs[j]
return lhs.depth > rhs.depth
})
for _, pend := range alldirs {
/*
* "Os.Remove" for a directory fails because the
* directory is not empty or for some other reason.
* Here, error reports other than empty directories
* are noise, so target only empty directories.
*/
fn := pend.path
ents, _ := os.ReadDir(fn)
if len(ents) == 0 {
rmerr := os.Remove(fn)
if rmerr != nil {
log.Print(fn, ": ", rmerr)
} else {
log.Printf("removed emptified dir: %s\n", fn)
}
}
}
}
func main() {
RmdirHier(os.Args[1:])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment