lines.go in Go
Count lines, words, and bytes like wc, for files or stdin.
// Count lines, words, and bytes for files or stdin, like wc.
package main
import (
"bufio"
"fmt"
"os"
)
type counts struct {
lines, words, bytes int
}
func count(r *bufio.Reader) counts {
var c counts
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
c.lines++
c.bytes += len(line) + 1
inWord := false
for _, ch := range line {
if ch == ' ' || ch == '\t' {
inWord = false
} else if !inWord {
inWord = true
c.words++
}
}
}
return c
}
func main() {
args := os.Args[1:]
if len(args) == 0 {
c := count(bufio.NewReader(os.Stdin))
fmt.Printf("%8d %8d %8d\n", c.lines, c.words, c.bytes)
return
}
var total counts
for _, name := range args {
f, err := os.Open(name)
if err != nil {
fmt.Fprintf(os.Stderr, "skip %s: %v\n", name, err)
continue
}
c := count(bufio.NewReader(f))
f.Close()
fmt.Printf("%8d %8d %8d %s\n", c.lines, c.words, c.bytes, name)
total.lines += c.lines
total.words += c.words
total.bytes += c.bytes
}
if len(args) > 1 {
fmt.Printf("%8d %8d %8d total\n", total.lines, total.words, total.bytes)
}
}
How it works
bufio.Scannerreads line by line.- A word counter tracks transitions into words.
- Multiple files also print a total row.
Keywords and builtins used here
continueelseforfuncifintlenrangereturnstructtypevar
The run, in numbers
- Lines
- 59
- Characters to type
- 1038
- Tokens
- 295
- Three-star pace
- 105 tpm
At the three-star pace of 105 tokens a minute, this run takes about 169 seconds.
Step 1 of 1 in Encore, step 30 of 30 in Language basics.