-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
143 lines (131 loc) · 3.68 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"flag"
"fmt"
"log"
"os"
"path/filepath"
"sort"
)
/*
Big File Finder, your BFF
To find all files under a path recursively which are above a minimum size limit.
*/
var (
pathsAboveRedSizeMBLimit = flag.Int("minsize", 500, "minimum size to display in MBs")
targetDir = flag.String("path", "/tmp", "path to scan")
listDir = flag.Bool("dir", false, "list big size directories also")
version = flag.Bool("version", false, "show me version")
debug = flag.Bool("debug", false, "show extra information")
)
func readDir(dirname string) ([]os.FileInfo, error) {
f, err := os.Open(dirname)
if err != nil {
return nil, err
}
list, err := f.Readdir(-1)
f.Close()
if err != nil {
return nil, err
}
sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() })
return list, nil
}
func sizeInHuman(size int64) (float64, string, string) {
floatSize := float64(size)
kbSize := floatSize / 1024
if kbSize < 1.0 {
return floatSize, fmt.Sprintf("%d bytes", size), "b"
}
mbSize := kbSize / 1024
if mbSize < 1.0 {
return kbSize, fmt.Sprintf("about %.2f KBs", kbSize), "kb"
}
gbSize := mbSize / 1024
if gbSize < 1.0 {
return mbSize, fmt.Sprintf("about %.2f MBs", mbSize), "mb"
}
return gbSize, fmt.Sprintf("about %.2f GBs", gbSize), "gb"
}
func changeSizeToMB(size float64, sizeType string) float64 {
if sizeType == "b" {
return (size / (1024 * 1024))
} else if sizeType == "kb" {
return (size / (1024))
} else if sizeType == "mb" {
return size
} else if sizeType == "gb" {
return size * 1024
}
return size
}
func calculateDirSize(dirPath string) (dirSize int64, fullDirSize float64, err error) {
err = filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if info.Mode().IsRegular() {
dirSize += info.Size()
}
return nil
})
size, _, sizeType := sizeInHuman(dirSize)
fullDirSize = changeSizeToMB(size, sizeType)
return
}
func analyzeSubDir(dirPath string, dirName string, sizeMBLimit float64) {
_, dirSize, err := calculateDirSize(dirPath)
if err != nil && *debug == true {
log.Printf("not able to get dir size for: %s", dirPath)
return
} else if float64(dirSize) >= sizeMBLimit {
if *listDir {
fmt.Printf("\n📁Path: %s\n\tName: %s\n\tSize: %.2f MB\n", dirPath, dirName, dirSize)
}
analyzeDir(dirPath)
}
}
func analyzeDir(pathToScan string) {
sizeMBLimit := float64(*pathsAboveRedSizeMBLimit)
if entries, err := readDir(pathToScan); err == nil {
for _, entry := range entries {
filepath := filepath.Join(pathToScan, entry.Name())
size, humanSize, sizeType := sizeInHuman(entry.Size())
if entry.IsDir() {
analyzeSubDir(filepath, entry.Name(), sizeMBLimit)
continue
}
if sizeType == "b" || sizeType == "kb" {
continue
} else if sizeType == "mb" && size < sizeMBLimit {
continue
} else if sizeType == "gb" {
mbSize := size * 1024
if mbSize < sizeMBLimit {
continue
}
}
fmt.Printf("\n📄Path: %s\n\tName: %s\n\tSize: %s\n", filepath, entry.Name(), humanSize)
}
} else {
log.Fatalf("error reading dir %s", pathToScan)
}
}
func main() {
flag.Parse()
fmt.Println(`
====================================================
___ _ ___ _ _ ___ _ _
| _ |_)__ _ | __(_) |___ | __(_)_ _ __| |___ _ _
| _ \ / _| | | _|| | / -_) | _|| | ' \/ _| / -_) '_|
|___/_\__, | |_| |_|_\___| |_| |_|_||_\__,_\___|_|
|___/
💣 📁 🕵️
====================================================
`)
if *version {
fmt.Println(" Version: 0.0.1")
} else {
analyzeDir(*targetDir)
}
fmt.Println(`
====================================================
`)
}