Source File: go-coreutils/find/main.go

package main

import (
  "fmt"
  "flag"
  "path/filepath"
  "regexp"
  "log"
  "io/fs"
)

type Opts struct {
  Name string
  Type string
}

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() {
  opts := ParseOpts()

  re, err := regexp.Compile(opts.Name)
  if err != nil { log.Fatal(err) }

  for _, start := range flag.Args() {
    filepath.WalkDir(start, func (path string, d fs.DirEntry, err error) error {
      if err != nil { log.Fatal(err) }

      if re.MatchString(path) {
        if opts.Type == "" {
          fmt.Println(path)
        } else if d.IsDir() && opts.Type == "d" {
          fmt.Println(path)
        } else if !d.IsDir() && opts.Type == "f" {
          fmt.Println(path)
        }
      }

      return nil
    })
  }
}