Systems & CLI · Beginner

minigrep: A Search Tool from Scratch

Build a command-line text search tool that recurses directories, matches patterns, and prints colored line-numbered hits.

Beginner8-12 hoursRust

minigrep is a command-line search tool you build in Rust that reads a pattern and a path from the user, walks the filesystem recursively, and prints every matching line with its filename, line number, and optional color highlighting. It is worth building because it teaches you how real tools like grep and ripgrep work internally while giving you hands-on practice with Rust's ownership model, error handling, and standard library I/O. The project is small enough to finish in a weekend yet rich enough to expose you to argument parsing, file traversal, regular expressions, and terminal output all in one coherent program.

What you build

  • Accepts a regex pattern and a file or directory path as CLI arguments via clap
  • Recursively walks directories using Rust's standard fs module or the walkdir crate
  • Matches each line against the pattern using the regex crate
  • Prints matching lines with filename, 1-based line number, and the matched text
  • Highlights matched substrings in color using ANSI escape codes when the terminal supports it
  • Exits with a non-zero code when no matches are found, enabling scripting and pipelines
  • Respects a --ignore-case flag for case-insensitive matching

What it teaches

  • Rust ownership, borrowing, and error propagation with the Result type across file I/O boundaries
  • Building typed CLI interfaces with clap's derive API including flags, options, and positional arguments
  • Compiling and applying regular expressions at runtime using the regex crate
  • Recursive filesystem traversal and handling of permission errors gracefully
  • Writing composable functions that separate argument parsing, file reading, matching, and output
  • Using ANSI escape codes or a terminal-color crate to produce readable CLI output

How it works

  1. 1

    Parse Args

    • pattern (regex string)
    • path (file or dir)

    clap derive struct

  2. 2

    Walk Filesystem

    • if file: open directly
    • if dir: recurse entries

    walkdir or std::fs

  3. 3

    Match Lines

    • compile Regex once
    • test each line

    regex crate

  4. 4

    Format Output

    • filename + line number
    • colored match highlight

    ANSI or colored crate

  5. 5

    Exit Code

    • 0 = matches found
    • 1 = no matches
fig. 01 — data flows from cli args through filesystem traversal and line matching to formatted terminal output.

Sign in to open the build guide

Free account. Get the step-by-step build and every resource link.

Sign in to continue

Take it further

  • Add a --count flag that prints only the number of matching lines per file instead of the lines themselves.
  • Support reading from stdin when no path argument is given, making minigrep composable in shell pipelines.
  • Respect .gitignore rules by integrating the ignore crate so that vendor directories and generated files are skipped automatically.

More like this

All projects