Created
August 24, 2012 13:35
-
-
Save rudenoise/3450591 to your computer and use it in GitHub Desktop.
My first go (console) app for analysing file length/size(bytes): sizeFiles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"flag" | |
"fmt" | |
"io" | |
"os" | |
"path/filepath" | |
"regexp" | |
"sort" | |
) | |
// cmd flags | |
var byBytes = flag.Bool("bytes", false, "order by byte length or line length") | |
var asc = flag.Bool("asc", false, "order ascending/descending") | |
var colour = flag.Bool("c", false, "colour output") | |
var lmt = flag.Int("limit", 0, "limit number of results") | |
var exclude = flag.String("exclude", "^$", "regexp pattern to exclude in file path") | |
var include = flag.String("include", "", "regexp pattern to include file path") | |
type File struct { | |
FilePath string | |
ByteLen int64 | |
Lines int | |
} | |
type Paths []File | |
func (p Paths) Len() int { return len(p) } | |
func (p Paths) Swap(i, j int) { p[i], p[j] = p[j], p[i] } | |
type ByByteLen struct{ Paths } | |
func (p ByByteLen) Less(i, j int) bool { return p.Paths[i].ByteLen < p.Paths[j].ByteLen } | |
type ByByteLenReverse struct{ Paths } | |
func (p ByByteLenReverse) Less(i, j int) bool { return p.Paths[i].ByteLen > p.Paths[j].ByteLen } | |
type ByLines struct{ Paths } | |
func (p ByLines) Less(i, j int) bool { return p.Paths[i].Lines < p.Paths[j].Lines } | |
type ByLinesReverse struct{ Paths } | |
func (p ByLinesReverse) Less(i, j int) bool { return p.Paths[i].Lines > p.Paths[j].Lines } | |
// SET UP pths TO HOLD COLLECTED DATA | |
var pths Paths | |
// COUNT LINES IN FILE | |
func countLines(filePath string) int { | |
count := 0 | |
contents, err := os.Open(filePath) | |
if err != nil { | |
panic(err) | |
} | |
defer contents.Close() | |
buf := bufio.NewReader(contents) | |
for { | |
read, err := buf.ReadString('\n') | |
if err == io.EOF { | |
break | |
} | |
if err != nil { | |
panic(err) | |
} | |
if read != "" { | |
count++ | |
} | |
} | |
return count | |
} | |
func visit(path string, f os.FileInfo, err error) error { | |
excludeMatch, err := regexp.MatchString(*exclude, path) | |
if err != nil { | |
panic(err) | |
} | |
includeMatch, err := regexp.MatchString(*include, path) | |
if err != nil { | |
panic(err) | |
} | |
if f.IsDir() == false && excludeMatch == false && includeMatch { | |
file := File{path, f.Size(), countLines(path)} | |
pths = append(pths, file) | |
} | |
return err | |
} | |
func out(p Paths, limit int) { | |
// print in colour | |
fmt.Printf("%7s\t%7s\t%s\n", "Lines", "Bytes", "Path") | |
for i := 0; i < limit; i++ { | |
// print out all collected file info | |
if p[i].FilePath != "." { | |
fmt.Printf("%7d\t%7d\t%s\n", p[i].Lines, p[i].ByteLen, p[i].FilePath) | |
} | |
} | |
} | |
func colourOut(p Paths, limit int) { | |
// print in colour | |
fmt.Printf("\033[1;32m%7s\t\033[1;33m%7s\t\033[1;37m%s\n\033[m", "Lines", "Bytes", "Path") | |
for i := 0; i < limit; i++ { | |
// print out all collected file info | |
if p[i].FilePath != "." { | |
fmt.Printf("\033[0;32m%7d\t\033[0;33m%7d\t\033[m%s\n", p[i].Lines, p[i].ByteLen, p[i].FilePath) | |
} | |
} | |
} | |
func main() { | |
flag.Parse() | |
// start at current dir or path from args | |
root := filepath.Dir(flag.Arg(0)) | |
// recurse each sub dir and run visit at each file location | |
err := filepath.Walk(root, visit) | |
// files parsed ok | |
if err != nil { | |
panic(err) | |
} | |
// order by args | |
if *byBytes { | |
if *asc { | |
sort.Sort(ByByteLen{pths}) | |
} else { | |
sort.Sort(ByByteLenReverse{pths}) | |
} | |
} else { | |
if *asc { | |
sort.Sort(ByLines{pths}) | |
} else { | |
sort.Sort(ByLinesReverse{pths}) | |
} | |
} | |
// decide length of output | |
length := len(pths) | |
if *lmt != 0 && *lmt <= length { | |
length = *lmt | |
} | |
// print output | |
if *colour { | |
colourOut(pths, length) | |
} else { | |
out(pths, length) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment