A GNU grep-compatible pattern matching tool written in Rust
Rust 99%
Nix <1%

README.md

Oxidized Grep #

Part of the overby.me monorepo, where this lives in safety/oxidized/grep and where all development happens.

It is also published on its own, as tangled.org/overby.me/oxidized-grep and github.com/overby-me/oxidized-grep. Both are read-only mirrors, rebuilt from the monorepo with josh: a commit made to either is overwritten by the next sync, so please open issues and pull requests on the monorepo.

A pure-Rust reimplementation of GNU grep(1) that aims to be output-compatible with the upstream tool. Passes 121/121 tests from the GNU grep 3.12 test suite.

Uses oxidized-pcre2 (pure Rust) for -P (Perl-compatible) mode, fancy-regex for BRE/ERE backreferences, and the regex crate otherwise.

Building #

nix build .#oxidized-grep
./result/bin/grep --help

The package installs grep, egrep, and fgrep (symlinks) into $out/bin.

Running the test suite #

Tests are run in a Nix sandbox. Each test script comes from the GNU grep source tarball; oxidized-grep is placed first on PATH (as grep/egrep/fgrep) and the script is executed against it.

# Run a single test
nix build .#checks.x86_64-linux.oxidized-grep-test-{name}

# View failure diff
nix log .#checks.x86_64-linux.oxidized-grep-test-{name}

See default.nix for the full list of test names. Tests time out after 120s.

Supported features #

All GNU grep 3.12 features exercised by the upstream test suite, including:

  • Basic, extended, Perl (-G/-E/-P), and fixed-string (-F) matching
  • Multiple patterns via repeated -e or -f FILE
  • -i, -v, -w, -x, -c, -l/-L, -m, -n, -b, -o, -H/-h, -q, -s
  • -A/-B/-C NUM and -NUM context
  • -r/-R recursive search with --include, --exclude, --exclude-dir
  • -z NUL-delimited I/O
  • --color=always/never/auto with GREP_COLORS support
  • Binary file detection, device-file skip (-D skip), -a/--binary-files=text
  • -T/--initial-tab, --label, --line-buffered

Known limitation #

Patterns with nested unbounded quantifiers (e.g. ((a+)*)+) trigger a MatchLimit-style error in -P mode on non-trivial inputs, mirroring PCRE2's exponential-backtracking safeguard. Short inputs and successful matches are unaffected.

Layout #

safety/oxidized/grep/
  Cargo.toml
  default.nix       # Nix package + test checks
  testsuite.nix     # Per-test Nix sandbox runner
  CHANGELOG.md
  README.md
  src/
    main.rs         # CLI entrypoint and exit codes
    args.rs         # Argument parsing
    files.rs        # File and directory walking
    grep.rs         # Per-file matching, context, output formatting
    matcher.rs      # Pattern compilation and matching dispatch
    pattern.rs      # BRE-to-ERE conversion and pattern validation