File: ./go.mod
   1 module ts
   2 
   3 go 1.18

     File: ./info.txt
   1 ts
   2 
   3 TimeStamp lines from standard input.

     File: ./main.go
   1 package main
   2 
   3 import (
   4     "bufio"
   5     "io"
   6     "os"
   7     "time"
   8 
   9     _ "embed"
  10 )
  11 
  12 //go:embed info.txt
  13 var info string
  14 
  15 func main() {
  16     if len(os.Args) > 1 {
  17         switch os.Args[1] {
  18         case `-h`, `-help`, `--h`, `--help`:
  19             os.Stderr.WriteString(info)
  20             return
  21         }
  22     }
  23 
  24     w := bufio.NewWriter(os.Stdout)
  25     defer w.Flush()
  26     timestamp(w, os.Stdin)
  27 }
  28 
  29 func timestamp(w *bufio.Writer, r io.Reader) {
  30     const gb = 1024 * 1024 * 1024
  31     sc := bufio.NewScanner(r)
  32     sc.Buffer(nil, 8*gb)
  33 
  34     const tsFormat = `2006-01-02 15:04:05`
  35     var buf [len(tsFormat)]byte
  36 
  37     for sc.Scan() {
  38         // start line with an ANSI-styled timestamp
  39         w.WriteString("\x1b[48;5;255m\x1b[38;5;24m")
  40         w.Write(time.Now().AppendFormat(buf[:0], tsFormat))
  41         w.WriteString("\x1b[0m ")
  42 
  43         // end line with the current input line
  44         w.Write(sc.Bytes())
  45         w.WriteString("\n")
  46 
  47         // flush output, to ensure updates show right away
  48         if err := w.Flush(); err != nil {
  49             // assume any output-write error is caused by a closed
  50             // pipe to a cmd-line app such as `head`, so just quit
  51             // without complaining
  52             break
  53         }
  54     }
  55 }