func main() { done := make(chan struct{}) defer close(done) files := flag.Args() if len(files) == 0 { files = make([]string, 1) files[0] = "-" } rows := util.Files2Rows(files, delim, done) if !*SortH { if header, ok := <-rows; ok { os.Stdout.Write(header.Data) os.Stdout.Write([]byte("\n")) } else { return } } // fill sort-window for len(sortwin) < cap(sortwin) { if row, ok := <-rows; ok { semisort(&row) } else { break } } // sort-n-flush window var flushrow *util.Row for len(sortwin) > 0 { sortwin, flushrow = sortwin[:len(sortwin)-1], sortwin[len(sortwin)-1] os.Stdout.Write(flushrow.Data) os.Stdout.Write([]byte("\n")) if row, ok := <-rows; ok { semisort(&row) } } }
func main() { done := make(chan struct{}) defer close(done) files := flag.Args() if len(files) == 0 { files = make([]string, 1) files[0] = "-" } rows := util.Files2Rows(files, Delim, done) var headermap map[string]int if !*noheader { if header, ok := <-rows; ok { headermap = util.HeaderMap(header) } else { return } } aggspec = Config(Keys, Pivots, Aggs, headermap) // Aggregate rows for row := range rows { key, err := row.JoinF(aggspec.Keys, Delim) if err != nil { panic(err) } pivot, err := row.JoinF(aggspec.Pivots, SubDelim) if err != nil { panic(err) } skey := string(key) pivots, p_ok := Aggregations[skey] // initialize pivots for this key if !p_ok { pivots = make(map[string][]Aggregator) Aggregations[skey] = pivots } spivot := string(pivot) aggs, a_ok := pivots[spivot] // initialize aggregators for this pivot if !a_ok { aggs = make([]Aggregator, len(aggspec.AggCtor)) for i, ctor := range aggspec.AggCtor { aggs[i] = ctor() } pivots[spivot] = aggs HeaderPivots[spivot] = struct{}{} // collect pivots } for i, agtor := range aggs { field_i := aggspec.Aggs[i] if field, err := row.Bytes(field_i); err == nil { agtor.Aggregate(field) } else { panic(err) } } } var pivots []string for p := range HeaderPivots { pivots = append(pivots, p) } out := bufio.NewWriter(os.Stdout) if !*noheader { Header(out, pivots) } Print(out, pivots) out.Flush() }