1package script 2 3import ( 4 "bufio" 5 "fmt" 6 "strings" 7 8 "github.com/hashicorp/go-multierror" 9) 10 11// Count represents the output of `wc` shell command. 12type Count struct { 13 // Stream can be used to pipe the output of wc. 14 Stream 15 // Count the number of lines, words and chars in the input. 16 Lines, Words, Chars int 17} 18 19// Wc counts the number of lines, words and characters. 20// 21// Shell command: `wc`. 22func (s Stream) Wc() Count { 23 defer s.Close() 24 25 var ( 26 count Count 27 errors *multierror.Error 28 ) 29 scanner := bufio.NewScanner(s) 30 for scanner.Scan() { 31 count.Lines++ 32 count.Chars += len(scanner.Text()) + 1 33 count.Words += countWords(scanner.Text()) 34 } 35 if err := scanner.Err(); err != nil { 36 errors = multierror.Append(errors, fmt.Errorf("scanning stream: %s", err)) 37 } 38 39 count.Stream = Stream{ 40 stage: "wc", 41 r: strings.NewReader(count.String()), 42 } 43 return count 44} 45 46func (c Count) String() string { 47 return fmt.Sprintf("%d\t%d\t%d\n", c.Lines, c.Words, c.Chars) 48} 49 50func countWords(s string) int { 51 // TODO: improve performance. 52 return len(strings.Fields(s)) 53} 54