diff --git a/main.go b/main.go index 9699987..564b4c1 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "bufio" "flag" "fmt" + "io" "os" "regexp" "strconv" @@ -25,6 +26,11 @@ var ( // they will be copied without any changes keepUnmatched = flag.Bool("k", false, "keep unmatched lines") + // if the amount of lines in stdin are not divisible by lineParseAmount, + // the last lines will be ignored completely. + // it may be useful to have a boolean flag for this behavior + lineParseAmount = flag.Int("n", 1, "amount of lines to feed into input pattern") + replacePattern = regexp.MustCompile(`\{(\d+)(?::(.*?))?\}`) ) @@ -36,8 +42,7 @@ func main() { panic(err) } - r := bufio.NewReader(os.Stdin) - for line, err := r.ReadString('\n'); err == nil; line, err = r.ReadString('\n') { + for line := range readLines(os.Stdin) { line = line[:len(line)-1] matches := pattern.FindStringSubmatch(line) @@ -52,6 +57,34 @@ func main() { } } +func readLines(r io.Reader) <-chan string { + ch := make(chan string, 10) + + go func(out chan<- string, source io.Reader) { + defer close(out) + + r := bufio.NewReader(source) + + for { + var line string + var err error + lines := make([]string, 0, *lineParseAmount) + for line, err = r.ReadString('\n'); err == nil; line, err = r.ReadString('\n') { + lines = append(lines, line) + if len(lines) == cap(lines) { + break + } + } + if err != nil { + return + } + out <- strings.Join(lines, "") + } + }(ch, r) + + return ch +} + func replaceVars(format string, vars ...string) string { replacements := replacePattern.FindAllStringSubmatch(format, -1)