A functional, type-safe grep implementation in pure Python 3.12+
bsce-mgrep is a modern, industrial-grade grep alternative built with functional programming principles. Unlike traditional grep, it provides semantic filtering capabilities through a safe expression language, making it ideal for complex log analysis and data processing workflows.
- 🔍 Powerful Matching: Literal strings and regular expressions with named capture groups
- 🧮 Semantic Filtering: Filter matched lines using safe expression evaluation (no
eval()) - 🛡️ Type-Safe: Full Python 3.12+ type hints with mypy strict mode compliance
- ⚡ Functional Core: Pure functions, immutability, and Railway-Oriented Programming
- 🏗️ Hexagonal Architecture: Clean separation of concerns, highly testable
- 📦 Zero Dependencies: Only stdlib +
resultlibrary for error handling
# Clone repository
git clone https://github.com/borba-sovereign/bsce-mgrep.git
cd bsce-mgrep
# Install dependencies
pip install -r requirements.txt
# Install package
pip install -e .# Simple literal match
mgrep app.log --match 'ERROR'
# Regex with named groups
mgrep app.log --match '/status=(?<code>\d+)/'
# Semantic filtering
mgrep app.log \
--match 'ERROR' \
--where 'line.length > 120' \
--where 'line.contains("timeout")'
# Pipeline from stdin
cat app.log | mgrep --match 'ERROR'
# Case-insensitive matching
mgrep app.log --match 'error' --case insensitive- Usage Guide - Complete CLI reference with examples
- Architecture - Technical deep-dive into design
- Contributing - Development guidelines
- Design Decisions - Rationale behind key choices
Every component is built with FP principles:
- Immutability: All data structures are frozen
- Pure Functions: No side effects outside I/O boundaries
- Composition: Complex behavior emerges from simple functions
- Railway-Oriented Programming: Explicit error handling via
Resulttype
Leverages Python 3.12+ features extensively:
type LineNumber = int
type MatchResult = Result[MatchContext, ErrorMessage]
@dataclass(frozen=True)
class Line:
number: LineNumber
content: strThe --where clause uses a manual expression parser (no eval()), preventing code injection while providing powerful filtering capabilities.
# Find all 5xx errors with request details
mgrep access.log \
--match '/status=(?<code>\d+)/' \
--where 'group("code") >= 500'
# Find long error messages
mgrep app.log \
--match 'ERROR' \
--where 'line.length > 200'# Extract user activity from logs
cat user-events.log | \
mgrep --match '/user=(?<id>\w+)/' \
--where 'line.contains("login")'
# Filter by line position
mgrep data.csv \
--match ',' \
--where 'line.number > 1' # Skip header- Python: 3.12 or higher
- Dependencies:
result(Railway-Oriented Programming)
Current Version: 0.1.0 (MVP)
- ✅ Literal and regex matching
- ✅ Named capture groups
- ✅ Semantic filtering (
--where) - ✅ Case sensitivity control
- ✅ File and stdin input
- 🔲
--emit jsonoutput format - 🔲 Performance optimizations (compiled patterns caching)
- 🔲 Colorized output
- 🔲 Multi-file processing
- 🔲 Watch mode for live logs
We welcome contributions! Please read our Contributing Guide for:
- Code style guidelines
- Development setup
- Testing requirements
- Pull request process
Author: Borba Sovereign Computing House Maintainer: André Borba
Inspired by functional programming practices from Bloomberg and Jane Street.
MIT License - see LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Built with ❤️ using Functional Programming principles