Example #1
0
File: tally.go Project: gaal/shstat
func tally(in io.Reader, w io.Writer, ifs *regexp.Regexp, ofs string, idx []int) error {
	sums := make([]int64, len(idx))
	p := internal.NewParter(ifs, idx)
	s := bufio.NewScanner(in)
	var nlines int
	for s.Scan() {
		var bad bool
		nlines++
		parts := p.Fields(s.Bytes())
		for i, v := range parts {
			n, err := strconv.ParseInt(string(v), 10, 64)
			if err != nil {
				bad = true
				continue
			}
			sums[i] += n
		}
		if bad && !*quiet {
			fmt.Fprintf(os.Stderr, "bad input: line %d\n", nlines)
		}
	}
	if err := s.Err(); err != nil {
		return err
	}
	for i, v := range sums {
		var sep string
		if i > 0 {
			sep = ofs
		}
		if _, err := fmt.Fprintf(w, "%s%d", sep, v); err != nil {
			return err
		}
	}
	if _, err := fmt.Fprintln(w, ""); err != nil {
		return err
	}
	return nil
}
Example #2
0
File: fld.go Project: gaal/shstat
func fld(in io.Reader, w io.Writer, ifs *regexp.Regexp, ofs string, idx []int) error {
	p := internal.NewParter(ifs, idx)
	ofsb := []byte(ofs)

	out := bufio.NewWriter(w)
	s := bufio.NewScanner(in)
	for s.Scan() {
		parts := p.Fields(s.Bytes())
		if _, err := out.Write(bytes.Join(parts, ofsb)); err != nil {
			return err
		}
		if _, err := out.Write([]byte("\n")); err != nil {
			return err
		}
	}
	if err := s.Err(); err != nil {
		return err
	}
	if err := out.Flush(); err != nil {
		return err
	}
	return nil
}
Example #3
0
File: hist.go Project: gaal/shstat
func (h *histogrammer) hist(in io.Reader) ([]keyCount, error) {
	h.hfmt, h.kavail, h.gavail = hlinefmt(h.termWidth, h.gt != gNone, h.ofs)

	key := func(line []byte) []byte { return line }
	if len(h.keys) > 0 {
		kp := internal.NewParter(h.ifs, h.keys)
		key = func(line []byte) []byte {
			parts := kp.Fields(line)
			// TODO: is there a better way to rejoin parted keys than hardcode
			// space? ofs is wrong, but ifs is a regexp.
			return bytes.Join(parts, []byte(" "))
		}
	}

	weight := func(line []byte) (int64, error) { return 1, nil }
	if h.weightCol != 0 {
		wp := internal.NewParter(h.ifs, []int{h.weightCol})
		weight = func(line []byte) (int64, error) {
			parts := wp.Fields(line)
			if len(parts) == 0 {
				return 0, errors.New("short line")
			}
			w, err := strconv.ParseInt(string(parts[0]), 10, 64)
			if err != nil {
				return 0, err
			}
			return w, nil
		}
	}

	d := make(map[string]int64)
	var nlines int
	s := bufio.NewScanner(in)
	if h.words {
		s.Split(bufio.ScanWords)
	}
	for s.Scan() {
		nlines++

		line := s.Bytes()
		w, err := weight(line)
		if err != nil {
			fmt.Fprintf(os.Stderr, "%v: %d", err, nlines)
			continue
		}
		k := string(key(line))
		d[k] += w
		if len(k) > h.maxKey {
			h.maxKey = len(k)
		}
	}
	if err := s.Err(); err != nil {
		return nil, err
	}

	var kc []keyCount
	for k, v := range d {
		kc = append(kc, keyCount{key: k, cnt: v})
	}
	sort.Sort(byCountKey(kc))
	if len(kc) > 0 {
		h.maxVal = abs(kc[0].cnt)
		if abs(kc[len(kc)-1].cnt) > h.maxVal {
			h.maxVal = abs(kc[len(kc)-1].cnt)
		}
	}
	h.gscale = float64(h.maxVal)
	if h.gt == gLog {
		h.gscale = math.Log2(float64(h.maxVal))
	}
	h.gscale /= float64(h.gavail)

	return kc, nil
}