Skip to content

Instantly share code, notes, and snippets.

@ajstarks
Created July 18, 2017 09:28
Show Gist options
  • Save ajstarks/04a61ace4fc8e18f51fda8da6adac017 to your computer and use it in GitHub Desktop.
Save ajstarks/04a61ace4fc8e18f51fda8da6adac017 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/csv"
"flag"
"fmt"
"io"
"os"
"strconv"
)
// getf turns a string slice of numbers into a slice of integers
func getf(s []string) []int {
fn := []int{}
for _, f := range s {
n, err := strconv.Atoi(f)
if err != nil {
continue
}
fn = append(fn, n)
}
return fn
}
// output displays fields of data
func output(s []string, w *csv.Writer, plain bool) {
if plain {
nl := len(s) - 1
for i := 0; i < nl; i++ {
fmt.Printf("%s\t", s[i])
}
fmt.Println(s[nl])
} else {
w.Write(s)
}
}
func main() {
var plainout = flag.Bool("plain", true, "plain output")
flag.Parse()
r := csv.NewReader(os.Stdin)
w := csv.NewWriter(os.Stdout)
r.LazyQuotes = true
r.TrailingComma = true
fields := getf(flag.Args())
// loop over the input, making output
for {
data, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
continue
}
if len(fields) > 0 { // output selected fields
selection := []string{}
for _, n := range fields {
if n >= 0 && n < len(data) {
selection = append(selection, data[n])
}
}
output(selection, w, *plainout)
} else { // or output all fields
output(data, w, *plainout)
}
}
w.Flush()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment