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

package main

import (
  "fmt"
  "flag"
  "strings"
  "log"
  "strconv"
  "bufio"
  "os"
)

type Opts struct {
  FieldOpt string
  Fields []int
  Delim string
}

func parse_opts() Opts {
  var opts Opts

  opts.Fields = make([]int, 0, 10)

  flag.StringVar(&opts.FieldOpt, "f", "", "fields list")
  flag.StringVar(&opts.Delim, "d", "\t", "delimiter byte")
  flag.Parse()

  if opts.FieldOpt == "" { log.Fatal("-f fields list required") }

  for _, num := range strings.Split(opts.FieldOpt, ",") {
    as_int, err := strconv.Atoi(num)
    if err != nil { log.Fatal("-f can only contain numbers") }

    opts.Fields = append(opts.Fields, as_int)
  }

  return opts
}

func main() {
  opts := parse_opts()

  scan := bufio.NewScanner(os.Stdin)
  for scan.Scan() {
    line := scan.Text()

    chopped := strings.Split(line, opts.Delim)

    for i, field_num := range opts.Fields {
      if field_num >= len(chopped) {
        fmt.Print("\n")
        continue
      }

      fmt.Print(chopped[field_num])

      if i < len(opts.Fields) - 1 {
        fmt.Print(opts.Delim)
      } else {
        fmt.Print("\n")
      }
    }
  }
}