go 32 lines · 4 steps

Counting matching lines in Go with bufio

A function that streams a file line by line and counts how many lines contain a substring, handling errors cleanly.

Explained by highlit
1package main
2 
3import (
4 "bufio"
5 "fmt"
6 "os"
7)
8 
9func countMatchingLines(path, needle string) (int, error) {
10 f, err := os.Open(path)
11 if err != nil {
12 return 0, err
13 }
14 defer f.Close()
15 
16 scanner := bufio.NewScanner(f)
17 buf := make([]byte, 0, 64*1024)
18 scanner.Buffer(buf, 1024*1024)
19 
20 count := 0
21 for scanner.Scan() {
22 line := scanner.Text()
23 if strings.Contains(line, needle) {
24 count++
25 }
26 }
27 
28 if err := scanner.Err(); err != nil {
29 return count, fmt.Errorf("reading %s: %w", path, err)
30 }
31 return count, nil
32}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Streaming a file with bufio.Scanner avoids loading the whole thing into memory.
  2. 2defer ties resource cleanup to the function's exit so it never leaks regardless of return path.
  3. 3A scanner can stop silently, so checking scanner.Err() after the loop is what makes the result trustworthy.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Counting matching lines in Go with bufio — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code