Install
Use the module directly in a Go project:
go get github.com/osvik/simplecsvThen import it where your command reads or transforms CSV data:
import "github.com/osvik/simplecsv"Your first transform
This complete program keeps active adults, selects the columns that belong in the export, and writes a new file.
package main
import (
"log"
"strconv"
"github.com/osvik/simplecsv"
)
func main() {
input, err := simplecsv.ReadCsvFileE("people.csv")
if err != nil {
log.Fatal(err)
}
active, ok := input.Where("status", "active")
if !ok {
log.Fatal("status field not found")
}
adults, ok := active.FilterByField("age", func(value string) bool {
age, err := strconv.Atoi(value)
return err == nil && age >= 18
})
if !ok {
log.Fatal("age field not found")
}
output, ok := adults.OnlyThisFields([]string{"id", "name", "age"})
if !ok {
log.Fatal("could not select fields")
}
if err := output.WriteCsvFileE("active-adults.csv"); err != nil {
log.Fatal(err)
}
}Use streams for Unix-style tools
File helpers are convenient, but simplecsv also reads from any io.Reader and writes to any io.Writer. That makes stdin and stdout natural command-line interfaces.
package main
import (
"log"
"os"
"github.com/osvik/simplecsv"
)
func main() {
input, err := simplecsv.ReadCsv(os.Stdin, ',')
if err != nil {
log.Fatal(err)
}
output, ok := input.WhereFold("status", "active")
if !ok {
log.Fatal("status field not found")
}
if err := output.WriteTo(os.Stdout, ','); err != nil {
log.Fatal(err)
}
}Three rules worth remembering
- Row zero is the header.Data rows start at index 1. Prefer
*ByField,Where, andFilterByFieldso header arithmetic stays out of your program. - Cells are strings.Convert at the edge of the operation with
strconv. Storage remains a predictablestringmodel. - Transformations return copies.Methods such as
Where,SortByField, andGroupBydo not mutate their receiver or share row slices.
Use error-returning variants such as JoinE, GroupByE, ConcatE, and ConcatByNameE. The original boolean APIs remain available for short scripts.
Next steps
Pick a workflow and copy the smallest recipe that matches it: