detect
A modern replacement for find/grep using an intuitive expression language.
- Readable syntax:
ext == ts AND size > 50kbinstead offind . -name "*.ts" -size +50k - Unified queries: Combine filename + content + metadata instead of chaining multiple processes
- Lazy evaluation: Detect checks cheap predicates first (filename, metadata) and short circuits whenever possible
Quick start • Installation • Query language • Examples
Traditional Unix tools require chaining multiple commands with cryptic syntax:
# Find Rust files importing BOTH tokio and serde
# Traditional approach - scan all .rs files, then scan matches a second time
|
Detect also supports searches inspecting structured data in YAML, TOML, and JSON files:
# Find Cargo.toml files with package edition 2018
# using regexes (may result in false positives)
# using cryptaliagy's tomlq crate
Installation
From crates.io
Building from source
Prerequisites: Rust toolchain (1.70+)
# Binary will be at ./target/release/detect
# Optionally install globally:
Quick start
Query language
Selectors
File Identity
| Selector | Type | Description | Example |
|---|---|---|---|
name / filename |
String | Full filename with extension | name == "README.md" |
basename / stem |
String | Filename without extension | basename == README |
ext / extension |
String | File extension (no dot) | ext == rs |
path |
String | Full absolute path | path contains /src/ |
dir / parent / directory |
String | Parent directory path | dir contains lib |
File Properties
| Selector | Type | Description | Example |
|---|---|---|---|
size |
Numeric | File size in bytes | size > 1mb |
type |
Enum | File type (parse-time validated) | type == file |
depth |
Numeric | Directory depth from search root | depth <= 3 |
Size units: kb, mb, gb, tb (e.g., 1.5mb, 500kb)
File types (case-insensitive): file, dir/directory, symlink/link, socket/sock, fifo/pipe, block/blockdev, char/chardev
Timestamps
| Selector | Type | Description | Example |
|---|---|---|---|
modified / mtime |
Temporal | Last modification time | modified > -7d |
created / ctime |
Temporal | File creation time | created > 2024-01-01 |
accessed / atime |
Temporal | Last access time | accessed < -1h |
Time formats: Relative -7d/-7days, -2h/-2hours, -1w/-1week (units: s, m/min, h/hr, d/day, w/week + plurals). Absolute 2024-01-15, 2024-01-15T10:30:00.
Content
| Selector | Type | Description | Example |
|---|---|---|---|
content / text / contents |
String | File text contents | content contains TODO |
Structured Data
Query YAML, JSON, and TOML:
Navigate with .field, .nested.field, [0], [*], ..field. Auto-converts between numbers and strings (yaml:.port == 8080 matches both 8080 and "8080"). Default max file size: 10MB (configurable with --max-structured-size).
Operators
| Type | Operators | Example |
|---|---|---|
| String | ==, !=, contains, ~=, in [a,b] |
content contains TODO |
| Numeric | ==, !=, >, <, >=, <= |
size > 1mb |
| Temporal | >, <, >=, <=, ==, != |
modified > -7d |
| Enum | ==, !=, in [a,b] |
type == file |
| Boolean | AND/&&, OR/` |
Precedence: NOT > AND > OR
Full reference: detect --operators
Examples
# File metadata combinations
# Content matching with regex
# Structured data navigation
# Multi-feature real-world queries
# Security scanning
# Migration from find/grep
# CLI options
More examples: detect --examples
Exit codes
Compatible with scripting and CI/CD pipelines (same as grep/ripgrep):
- 0 - Matches found
- 1 - No matches
- 2 - Error (parse error, directory not found, etc.)
# Use in conditionals
if ; then
fi
# CI: fail build if TODOs found
&&
Performance
Queries are evaluated in four phases: name → metadata → structured → content. Each phase can eliminate files before more expensive operations. Content is never read unless the file passes all earlier checks.
Respects .gitignore by default. Traverses directories in parallel. Structured data parsing is limited to 10MB files (configurable).
Contributing
Contributions welcome. File an issue before major changes.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.