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

package main

import (
  "fmt"
  "bufio"
  "os"
  "log"
  "flag"
  "io"
)

func TailFile(file io.Reader, count int) {
  scan := bufio.NewScanner(file)
  var lines []string

  for scan.Scan() {
    lines = append(lines, scan.Text())
  }

  if scan.Err() != nil { log.Fatal(scan.Err()) }

  start := len(lines) - count
  if start < 0 { start = 0 }

  for line := int(start); line < len(lines); line++ {
    fmt.Println(lines[line])
  }
}

type Opts struct {
  Count int
  Files []string
}

func ParseOpts() Opts {
  var opts Opts

  flag.IntVar(&opts.Count, "n", 10, "number of lines")
  flag.Parse()

  opts.Files = flag.Args()

  return opts
}

func main() {
  opts := ParseOpts()

  if len(opts.Files) > 0 {
    for _, fname := range opts.Files {
      file, err := os.Open(fname)
      if err != nil { log.Fatal(err) }

      TailFile(file, opts.Count)
    }
  } else {
    TailFile(os.Stdin, opts.Count)
  }
}