Quick code review and clean up to make them all about the same in style.

master
Zed A. Shaw 2 days ago
parent 509750b2ab
commit f851eb004b
  1. 12
      cat/main.go
  2. 4
      cut/main.go
  3. 69
      find/main.go
  4. 63
      grep/main.go
  5. 63
      ls/main.go
  6. 30
      nohup/main.go
  7. 111
      numfmt/main.go
  8. 12
      od/main.go
  9. 48
      sha512sum/main.go
  10. 12
      sort/main.go
  11. 8
      stat/main.go
  12. 28
      tail/main.go
  13. 10
      uniq/main.go
  14. 8
      wc/main.go

@ -8,19 +8,13 @@ import (
"strings" "strings"
) )
func Fail(err error, format string, v ...any) {
err_format := fmt.Sprintf("ERROR: %v; %s", err, format)
log.Printf(err_format, v...)
os.Exit(1)
}
type Opts struct { type Opts struct {
Number bool Number bool
Squeeze bool Squeeze bool
Filenames []string Filenames []string
} }
func parse_opts() (Opts) { func ParseOpts() (Opts) {
var opts Opts var opts Opts
flag.BoolVar(&opts.Number, "n", false, "Number all nonempty output lines, starting with 1") flag.BoolVar(&opts.Number, "n", false, "Number all nonempty output lines, starting with 1")
@ -38,12 +32,12 @@ func parse_opts() (Opts) {
} }
func main() { func main() {
opts := parse_opts() opts := ParseOpts()
for _, filename := range opts.Filenames { for _, filename := range opts.Filenames {
in_file, err := os.ReadFile(filename) in_file, err := os.ReadFile(filename)
if err != nil { Fail(err, "cannot open %s:", filename) } if err != nil { log.Fatalf("cannot open %s: %v", filename, err) }
if(opts.Number) { if(opts.Number) {
count := 1 count := 1

@ -16,7 +16,7 @@ type Opts struct {
Delim string Delim string
} }
func parse_opts() Opts { func ParseOpts() Opts {
var opts Opts var opts Opts
opts.Fields = make([]int, 0, 10) opts.Fields = make([]int, 0, 10)
@ -38,7 +38,7 @@ func parse_opts() Opts {
} }
func main() { func main() {
opts := parse_opts() opts := ParseOpts()
scan := bufio.NewScanner(os.Stdin) scan := bufio.NewScanner(os.Stdin)
for scan.Scan() { for scan.Scan() {

@ -10,38 +10,45 @@ import (
) )
type Opts struct { type Opts struct {
Name string Name string
Type string Type string
Print bool }
func ParseOpts() Opts {
var opts Opts
flag.StringVar(&opts.Name, "name", "", "regex of file")
flag.StringVar(&opts.Type, "type", "f", "type to find")
flag.Parse()
if flag.NArg() == 0 {
log.Fatal("USAGE: find -name <regex> [-type d/f] <dir> [dir dir]")
}
return opts
} }
func main() { func main() {
var opts Opts opts := ParseOpts()
flag.StringVar(&opts.Name, "name", "", "regex of file") re, err := regexp.Compile(opts.Name)
flag.StringVar(&opts.Type, "type", "f", "type to find") if err != nil { log.Fatal(err) }
flag.Parse()
for _, start := range flag.Args() {
re, err := regexp.Compile(opts.Name) filepath.WalkDir(start, func (path string, d fs.DirEntry, err error) error {
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
if flag.NArg() == 0 { if re.MatchString(path) {
log.Fatal("USAGE: find -name <regex> [-type d/f] <dir> [dir dir]") if opts.Type == "" {
} fmt.Println(path)
} else if d.IsDir() && opts.Type == "d" {
for _, start := range flag.Args() { fmt.Println(path)
filepath.WalkDir(start, func (path string, d fs.DirEntry, err error) error { } else if !d.IsDir() && opts.Type == "f" {
if re.MatchString(path) && opts.Print { fmt.Println(path)
if opts.Type == "" { }
fmt.Println(path) }
} else if d.IsDir() && opts.Type == "d" {
fmt.Println(path) return nil
} else if !d.IsDir() && opts.Type == "f" { })
fmt.Println(path) }
}
}
return nil
})
}
} }

@ -11,42 +11,43 @@ import (
) )
func ScanInput(input io.Reader, exp string, prefix string) { func ScanInput(input io.Reader, exp string, prefix string) {
scan := bufio.NewScanner(input) scan := bufio.NewScanner(input)
re, err := regexp.Compile(exp) re, err := regexp.Compile(exp)
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
for scan.Scan() { for scan.Scan() {
line := scan.Text() line := scan.Text()
if re.MatchString(line) { if re.MatchString(line) {
if prefix != "" { if prefix != "" {
fmt.Print(prefix, ": ") fmt.Print(prefix, ": ")
} }
fmt.Println(line) fmt.Println(line)
} }
} }
} }
func main() { func main() {
flag.Parse() // NOTE: can we avoid flag here since it's just raw args?
flag.Parse()
args := flag.Args()
args := flag.Args()
if len(args) == 0 {
log.Fatal("USAGE: grep <regex> [files...]") if len(args) == 0 {
} else if len(args) == 1 { log.Fatal("USAGE: grep <regex> [files...]")
ScanInput(os.Stdin, args[0], "") } else if len(args) == 1 {
} else { ScanInput(os.Stdin, args[0], "")
exp := args[0] } else {
files := args[1:] exp := args[0]
files := args[1:]
for _, file := range files {
input, err := os.Open(file) for _, file := range files {
if err != nil { log.Fatal(err) } input, err := os.Open(file)
if err != nil { log.Fatal(err) }
ScanInput(input, exp, file)
} ScanInput(input, exp, file)
} }
}
} }

@ -7,36 +7,47 @@ import (
"flag" "flag"
) )
func main() { type Opts struct {
var recurse bool Recurse bool
Paths []string
flag.BoolVar(&recurse, "R", false, "recursive listing") }
flag.Parse()
paths := flag.Args() func ParseOpts() Opts {
var opts Opts
if len(paths) == 0 { flag.BoolVar(&opts.Recurse, "R", false, "recursive listing")
paths = append(paths, ".") flag.Parse()
}
for _, what := range paths { opts.Paths = flag.Args()
if flag.NArg() > 1 {
fmt.Printf("\n%s:\n", what)
}
filepath.WalkDir(what, func (path string, d fs.DirEntry, err error) error { if len(opts.Paths) == 0 {
if path == what { return nil } opts.Paths = append(opts.Paths, ".")
}
if d.IsDir() && recurse { return opts
fmt.Printf("\n%s:\n", path) }
} else if d.IsDir() {
fmt.Printf("%s\n", filepath.Base(path))
return fs.SkipDir
} else {
fmt.Printf("%s\n", filepath.Base(path))
}
return nil func main() {
}) opts := ParseOpts()
}
for _, what := range opts.Paths {
if flag.NArg() > 1 {
fmt.Printf("\n%s:\n", what)
}
filepath.WalkDir(what, func (path string, d fs.DirEntry, err error) error {
if path == what { return nil }
if d.IsDir() && opts.Recurse {
fmt.Printf("\n%s:\n", path)
} else if d.IsDir() {
fmt.Printf("%s\n", filepath.Base(path))
return fs.SkipDir
} else {
fmt.Printf("%s\n", filepath.Base(path))
}
return nil
})
}
} }

@ -12,26 +12,26 @@ import (
) )
func Exec(prog string, args []string, target_out io.Writer) { func Exec(prog string, args []string, target_out io.Writer) {
cmd := exec.Command(prog, args...) cmd := exec.Command(prog, args...)
if cmd.Err != nil { log.Fatal(cmd.Err) } if cmd.Err != nil { log.Fatal(cmd.Err) }
in, err := cmd.StdinPipe() in, err := cmd.StdinPipe()
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
in.Close() in.Close()
stdout, err := cmd.StdoutPipe() stdout, err := cmd.StdoutPipe()
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
stderr, err := cmd.StderrPipe() stderr, err := cmd.StderrPipe()
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
output := io.MultiReader(stdout, stderr) output := io.MultiReader(stdout, stderr)
err = cmd.Start() err = cmd.Start()
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
_, err = io.Copy(target_out, output) _, err = io.Copy(target_out, output)
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
} }
func OpenOutput() io.Writer { func OpenOutput() io.Writer {
@ -53,7 +53,7 @@ func main() {
args := flag.Args() args := flag.Args()
if flag.NArg() == 0 { if flag.NArg() == 0 {
log.Fatal("USAGE: nohup cmd [args]") log.Fatal("USAGE: nohup cmd [args]")
} }
output := OpenOutput() output := OpenOutput()

@ -1,75 +1,78 @@
package main package main
import ( import (
"fmt" "fmt"
"flag" "flag"
"strconv" "strconv"
"log" "log"
"math" "math"
"bufio" "bufio"
"os" "os"
) )
type Opts struct { type Opts struct {
From string From string
To string To string
Numbers []string
} }
func parse_opts() (Opts, []string) { func ParseOpts() Opts {
var opts Opts var opts Opts
flag.StringVar(&opts.From, "from", "", "Convert from") flag.StringVar(&opts.From, "from", "", "Convert from")
flag.StringVar(&opts.To, "to", "", "Convert to") flag.StringVar(&opts.To, "to", "", "Convert to")
flag.Parse() flag.Parse()
return opts, flag.Args() opts.Numbers = flag.Args()
return opts
} }
func to_si(num string) string { func to_si(num string) string {
number, err := strconv.ParseFloat(num, 64) number, err := strconv.ParseFloat(num, 64)
if err != nil { log.Fatal("that's not a number") } if err != nil { log.Fatal("that's not a number") }
mag := math.Floor(math.Log10(number)) mag := math.Floor(math.Log10(number))
switch { switch {
case mag < 3: case mag < 3:
return num return num
case mag == 3: case mag == 3:
// need to separate k from hundres // need to separate k from hundres
as_k := math.Floor(float64(number) / 1000.0) as_k := math.Floor(float64(number) / 1000.0)
mod := math.Ceil(float64(int(number) % 1000)) mod := math.Ceil(float64(int(number) % 1000))
return fmt.Sprintf("%d.%dk", int(as_k), int(mod)) return fmt.Sprintf("%d.%dk", int(as_k), int(mod))
case mag > 3 && mag < 6: case mag > 3 && mag < 6:
as_m := math.Ceil(float64(number) / 1000.0) as_m := math.Ceil(float64(number) / 1000.0)
return fmt.Sprintf("%dk", int(as_m)) return fmt.Sprintf("%dk", int(as_m))
case mag == 6: case mag == 6:
// need to separate mil from k // need to separate mil from k
as_m := math.Floor(float64(number) / 1000000.0) as_m := math.Floor(float64(number) / 1000000.0)
mod := math.Ceil(float64(int(number) % 1000000) / 1000.0) mod := math.Ceil(float64(int(number) % 1000000) / 1000.0)
return fmt.Sprintf("%d.%dM", int(as_m), int(mod)) return fmt.Sprintf("%d.%dM", int(as_m), int(mod))
case mag > 6 && mag <= 9: case mag > 6 && mag <= 9:
as_m := math.Ceil(float64(number) / 1000000.0) as_m := math.Ceil(float64(number) / 1000000.0)
return fmt.Sprintf("%dM", int(as_m)) return fmt.Sprintf("%dM", int(as_m))
default: default:
return fmt.Sprintf("%sbesos", num) return fmt.Sprintf("%sbesos", num)
} }
} }
func main() { func main() {
opts, nums := parse_opts() opts := ParseOpts()
if opts.From != "" { if opts.From != "" {
log.Fatal("you should implement this") log.Fatal("you should implement this")
} }
if len(nums) == 0 { if len(opts.Numbers) == 0 {
scanner := bufio.NewScanner(os.Stdin) scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() { for scanner.Scan() {
num := scanner.Text() num := scanner.Text()
fmt.Println(to_si(num)) fmt.Println(to_si(num))
} }
} else { } else {
for _, num := range nums { for _, num := range opts.Numbers {
fmt.Println(to_si(num)) fmt.Println(to_si(num))
}
} }
}
} }

@ -8,12 +8,6 @@ import (
"bufio" "bufio"
) )
func Fail(err error, format string, v ...any) {
err_format := fmt.Sprintf("ERROR: %v; %s", err, format)
log.Printf(err_format, v...)
os.Exit(1)
}
type Opts struct { type Opts struct {
Width int Width int
Filenames []string Filenames []string
@ -22,7 +16,7 @@ type Opts struct {
Format string Format string
} }
func parse_opts() (Opts) { func ParseOpts() (Opts) {
var opts Opts var opts Opts
flag.IntVar(&opts.Width, "w", 16, "Width of output grid") flag.IntVar(&opts.Width, "w", 16, "Width of output grid")
@ -46,12 +40,12 @@ func parse_opts() (Opts) {
} }
func main() { func main() {
opts := parse_opts() opts := ParseOpts()
for _, filename := range opts.Filenames { for _, filename := range opts.Filenames {
reader, err := os.Open(filename) reader, err := os.Open(filename)
defer reader.Close() defer reader.Close()
if err != nil { Fail(err, "can't open: %s", filename) } if err != nil { log.Fatalf("can't open: %s: %v", filename, err) }
buf := bufio.NewReader(reader) buf := bufio.NewReader(reader)
count := buf.Size() count := buf.Size()

@ -1,45 +1,45 @@
package main package main
import ( import (
"fmt" "fmt"
"flag" "flag"
"os" "os"
"log" "log"
"crypto/sha512" "crypto/sha512"
) )
type Opts struct { type Opts struct {
Inputs []string Inputs []string
} }
func parse_opts() Opts { func ParseOpts() Opts {
var opts Opts var opts Opts
flag.Parse() flag.Parse()
opts.Inputs = flag.Args() opts.Inputs = flag.Args()
return opts return opts
} }
func to_hex(hash [sha512.Size]byte) string { func ToHex(hash [sha512.Size]byte) string {
result := "" result := ""
for _, b := range hash { for _, b := range hash {
result += fmt.Sprintf("%x", b) result += fmt.Sprintf("%x", b)
} }
return result return result
} }
func main() { func main() {
opts := parse_opts() opts := ParseOpts()
for _, fname := range opts.Inputs { for _, fname := range opts.Inputs {
in_data, err := os.ReadFile(fname) in_data, err := os.ReadFile(fname)
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
hash := sha512.Sum512(in_data) hash := sha512.Sum512(in_data)
fmt.Println(to_hex(hash), fname) fmt.Println(ToHex(hash), fname)
} }
} }

@ -15,7 +15,7 @@ type Opts struct {
Numeric bool Numeric bool
} }
func parse_opts() Opts { func ParseOpts() Opts {
var opts Opts var opts Opts
flag.BoolVar(&opts.IgnoreCase, "f", false, "ignore case") flag.BoolVar(&opts.IgnoreCase, "f", false, "ignore case")
@ -26,7 +26,7 @@ func parse_opts() Opts {
return opts return opts
} }
func numeric_sort(a string, b string) int { func NumericSort(a string, b string) int {
a_int, a_err := strconv.Atoi(a) a_int, a_err := strconv.Atoi(a)
b_int, b_err := strconv.Atoi(b) b_int, b_err := strconv.Atoi(b)
@ -37,13 +37,13 @@ func numeric_sort(a string, b string) int {
} }
} }
func ignore_case_sort(a string, b string) int { func IgnoreCase(a string, b string) int {
return strings.Compare(strings.ToLower(a), strings.ToLower(b)) return strings.Compare(strings.ToLower(a), strings.ToLower(b))
} }
func main() { func main() {
lines := make([]string, 0, 100) lines := make([]string, 0, 100)
opts := parse_opts() opts := ParseOpts()
scan := bufio.NewScanner(os.Stdin) scan := bufio.NewScanner(os.Stdin)
@ -53,9 +53,9 @@ func main() {
} }
if opts.Numeric { if opts.Numeric {
slices.SortFunc(lines, numeric_sort) slices.SortFunc(lines, NumericSort)
} else if opts.IgnoreCase{ } else if opts.IgnoreCase{
slices.SortFunc(lines, ignore_case_sort) slices.SortFunc(lines, IgnoreCase)
} else { } else {
slices.Sort(lines) slices.Sort(lines)
} }

@ -10,10 +10,10 @@ import (
func PrintStat(stat fs.FileInfo) { func PrintStat(stat fs.FileInfo) {
fmt.Printf("File: %s\nSize: %d\nAccess: %v\nModify: %v", fmt.Printf("File: %s\nSize: %d\nAccess: %v\nModify: %v",
stat.Name(), stat.Name(),
stat.Size(), stat.Size(),
stat.Mode(), stat.Mode(),
stat.ModTime()) stat.ModTime())
} }
func main() { func main() {

@ -27,21 +27,33 @@ func TailFile(file io.Reader, count int) {
} }
} }
func main() { type Opts struct {
var count int Count int
Files []string
}
flag.IntVar(&count, "n", 10, "number of lines") func ParseOpts() Opts {
var opts Opts
flag.IntVar(&opts.Count, "n", 10, "number of lines")
flag.Parse() flag.Parse()
if flag.NArg() > 0 { opts.Files = flag.Args()
files := flag.Args()
for _, fname := range files { return opts
}
func main() {
opts := ParseOpts()
if len(opts.Files) > 0 {
for _, fname := range opts.Files {
file, err := os.Open(fname) file, err := os.Open(fname)
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
TailFile(file, count) TailFile(file, opts.Count)
} }
} else { } else {
TailFile(os.Stdin, count) TailFile(os.Stdin, opts.Count)
} }
} }

@ -7,13 +7,13 @@ import (
"strings" "strings"
"flag" "flag"
) )
type Opts struct { type Opts struct {
IgnoreCase bool IgnoreCase bool
Count bool Count bool
} }
func ParseOpts() Opts {
func parse_opts() Opts {
var opts Opts var opts Opts
flag.BoolVar(&opts.IgnoreCase, "i", false, "ignore case") flag.BoolVar(&opts.IgnoreCase, "i", false, "ignore case")
@ -23,7 +23,7 @@ func parse_opts() Opts {
return opts return opts
} }
func string_equal(a string, b string, ignore_case bool) bool { func StringEqual(a string, b string, ignore_case bool) bool {
if ignore_case { if ignore_case {
a = strings.ToLower(a) a = strings.ToLower(a)
b = strings.ToLower(b) b = strings.ToLower(b)
@ -36,12 +36,12 @@ func main() {
scan := bufio.NewScanner(os.Stdin) scan := bufio.NewScanner(os.Stdin)
seen_line := "" seen_line := ""
seen_count := 0 seen_count := 0
opts := parse_opts() opts := ParseOpts()
for scan.Scan() { for scan.Scan() {
line := scan.Text() line := scan.Text()
if !string_equal(line, seen_line, opts.IgnoreCase) { if !StringEqual(line, seen_line, opts.IgnoreCase) {
if opts.Count { if opts.Count {
fmt.Print(seen_count, " ") fmt.Print(seen_count, " ")
} }

@ -26,7 +26,7 @@ type Counts struct {
} }
func parse_opts() (Opts, []string) { func ParseOpts() (Opts, []string) {
var opts Opts var opts Opts
flag.BoolVar(&opts.Bytes, "c", false, "Count bytes") flag.BoolVar(&opts.Bytes, "c", false, "Count bytes")
@ -48,7 +48,7 @@ func parse_opts() (Opts, []string) {
} }
func count_file(opts *Opts, filename string) Counts { func CountFile(opts *Opts, filename string) Counts {
var counts Counts var counts Counts
in_file, err := os.Open(filename) in_file, err := os.Open(filename)
@ -104,10 +104,10 @@ func print_count(opts *Opts, count *Counts, file string) {
} }
func main() { func main() {
opts, files := parse_opts() opts, files := ParseOpts()
for _, file := range files { for _, file := range files {
count := count_file(&opts, file) count := CountFile(&opts, file)
print_count(&opts, &count, file) print_count(&opts, &count, file)
} }
} }

Loading…
Cancel
Save