func makeReader(filepath string, c *config) (*yacr.Reader, io.ReadCloser) { in, err := yacr.Zopen(filepath) if err != nil { log.Fatalf("Error while opening file: '%s' (%s)\n", filepath, err) } reader := yacr.NewReader(in, c.sep, c.quoted, c.guess) return reader, in }
func grep(pattern *regexp.Regexp, f string, config *config) (found bool, err error) { //fmt.Println(f, config) in, err := yacr.Zopen(f) if err != nil { return } defer in.Close() reader := yacr.NewReader(in, config.sep, config.quoted, config.guess) var headers []string if config.noHeader && !config.descMode { } else { for reader.Scan() { headers = append(headers, reader.Text()) if reader.EndOfRecord() { break } } // TODO Try to guess/fix the separator if an error occurs (or if only one column is found) if err = reader.Err(); err != nil { return } //fmt.Printf("Headers: %v (%d)\n", headers) } //tw := tabwriter.NewWriter(os.Stdout, 8, 1, 8, '\t', tabwriter.Debug) tw := tabwriter.NewWriter(os.Stdout, 0, 4, 2, ' ', 0) if config.descMode { fmt.Println(f, ":") for i, value := range headers { tw.Write([]byte(fmt.Sprintf("%d\t%s\n", i+config.start, value))) } tw.Flush() return } var values = make([][]byte, 0, 10) var v, cv []byte orig := values i := 0 for reader.Scan() { v = reader.Bytes() // must be copied if i < len(orig) { cv = orig[i] cv = append(cv[:0], v...) } else { cv = make([]byte, len(v)) copy(cv, v) } values = append(values, cv) if !reader.EndOfRecord() { i++ continue } if match(config.fields, pattern, values) { if !found { fmt.Println(f, ":") found = true } fmt.Println("-") for i, value := range values { if config.noHeader { tw.Write([]byte(fmt.Sprintf("%d\t%s\n", i+config.start, value))) } else if i < len(headers) { tw.Write([]byte(fmt.Sprintf("%d\t%s\t%s\n", i+config.start, headers[i], value))) } else { tw.Write([]byte(fmt.Sprintf("%d\t%s\t%s\n", i+config.start, "???", value))) } } tw.Flush() } orig = values values = values[:0] i = 0 } err = reader.Err() return }