Video Coming Soon...

Created by Zed A. Shaw Updated 2026-01-15 05:25:56

45: grep

The grep command is an extremely useful tool. It searches through files--even recursively--looking for patterns of text. These patterns use something called a "regular expression", or "regex" for short. A regex uses simple characters to create a matching pattern that can search for things like, "all numbers starting with 0 through 9 before a lowercase letter."

Here's a quick regex crash course:

After that you can put any text you want and those letters get matched exactly. Here's some regex to try on your own code:

The Challenge

Your grep should take a single regex and scan either a listed number of files or the os.Stdin input stream. It should also be able to process the three example regex I gave you and run on your main.go file.

The documentation for grep is:

Requirements

The only package that is mandatory for grep is the regexp package. Here's what I used:

See the list of requirements

Spoilers

Here's my quick implementation of grep to get you going. Can you do better?

See my first version codeView Source file go-coreutils/grep/main.go Only

package main

import (
  "fmt"
  "regexp"
  "os"
  "bufio"
  "flag"
  "log"
  "io"
)

func ScanInput(input io.Reader, exp string, prefix string) {
  scan := bufio.NewScanner(input)
  re, err := regexp.Compile(exp)

  if err != nil { log.Fatal(err) }

  for scan.Scan() {
    line := scan.Text()

    if re.MatchString(line) {
      if prefix != "" {
        fmt.Print(prefix, ": ")
      }

      fmt.Println(line)
    }
  }
}

func main() {
  // NOTE: can we avoid flag here since it's just raw args?
  flag.Parse()

  args := flag.Args()

  if len(args) == 0 {
    log.Fatal("USAGE: grep <regex> [files...]")
  } else if len(args) == 1 {
    ScanInput(os.Stdin, args[0], "")
  } else {
    exp := args[0]
    files := args[1:]

    for _, file := range files {
      input, err := os.Open(file)
      if err != nil { log.Fatal(err) }

      ScanInput(input, exp, file)
    }
  }
}

Testing It

If you want to push your learning further then you can try to implement an automated test for this. I actually need to learn how to test utilities like this with Go, so for now just consider this an extra challenge for later until I learn how to teach it.

Previous Lesson Next Lesson

Register for The Pro-Webdev Mega Bundle

Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.