# sd — Intuitive Find & Replace CLI, a Friendlier Alternative to sed > sd replaces sed for most find-and-replace needs with a far simpler syntax. No escaping madness, no BRE/ERE confusion, no differences between GNU and BSD — just sed 99% of us actually wanted. ## Install Save as a script file and run: # sd — Simpler sed for Find & Replace ## Quick Use ```bash # macOS brew install sd # Cargo cargo install sd --locked # Basic find + replace echo "hello world" | sd world everyone # hello everyone # In-place file edit sd 'foo' 'bar' file.txt # Regex with capture groups sd 'v(\d+)\.(\d+)\.(\d+)' 'version_$1_$2_$3' changelog.md # Preview before applying sd -p 'foo' 'bar' *.md ``` ## Introduction sd (stream editor, but friendlier) is a Rust utility that does what most people actually use sed for: find and replace, possibly with regex, possibly in place. It throws out sed's cryptic single-letter command language and inconsistent BSD vs GNU behavior, leaving a single clean interface. With over 7,000 GitHub stars, sd is the "just works" replacement for 90% of sed invocations. The other 10% — complex multi-line addressing, d/p/y commands — still need sed or awk, but for the common case, sd is faster and easier to remember. ## What sd Does sd takes two positional arguments: the pattern (regex by default) and the replacement. Flags control in-place editing (`-i`), literal strings (`-s`), preview (`-p`), and file-list mode (`-f`). Capture groups work with `$1` `$2` etc. The regex engine is Rust's `regex` crate (Perl-like, not POSIX), so features like non-greedy quantifiers and lookarounds work as expected. ## Architecture Overview ``` stdin / file | [sd (Rust)] arg 1: PATTERN arg 2: REPLACEMENT | [Regex engine (Rust `regex`)] Perl-like syntax named + numbered captures | [Substitution] $1, $2, ${name} for captures no re-escaping madness | stdout / in-place file edit ``` ## Self-Hosting & Configuration ```bash # Common tasks # Rename imports across a TS repo (preview first) sd -p '@oldorg/(\w+)' '@neworg/$1' src/**/*.ts sd '@oldorg/(\w+)' '@neworg/$1' src/**/*.ts # Fix trailing whitespace sd ' +$' '' **/*.md # Rewrite URLs in docs sd 'https://old.example.com' 'https://new.example.com' docs/**/*.md # Literal string (no regex) sd -s '.foo.' '.bar.' file.txt # Use with find + xargs for portability find . -name '*.js' -print0 | xargs -0 sd 'const (' 'let (' ``` ## Key Features - **Clean syntax** — 2 args: pattern and replacement (vs sed's `s/foo/bar/g`) - **Perl regex** — non-greedy, lookahead/lookbehind, named captures - **In-place editing** — no `-i.bak` drama, uses atomic rename - **Preview mode** — `-p` shows what would change without writing - **Literal mode** — `-s` for literal string replace (no regex escaping) - **Cross-platform** — same behavior on macOS, Linux, Windows (no BSD/GNU split) - **Fast** — Rust regex engine, multi-file in parallel - **Unicode aware** — UTF-8 by default ## Comparison with Similar Tools | Feature | sd | sed | perl -pi -e | awk | rg --replace | |---|---|---|---|---|---| | Learning curve | Very low | High (arcane) | Medium | High | Very low | | Regex flavor | Rust (Perl-like) | POSIX BRE/ERE | Perl | POSIX ERE | Rust (Perl-like) | | In-place | Yes (-i) | Yes (-i, tricky flags) | Yes (-i) | Need wrapper | Yes (--replace with rewrite) | | Cross-platform consistency | Yes | BSD/GNU differ | Yes | Varies | Yes | | Multi-file parallelism | Yes | Sequential | Sequential | Sequential | Yes | | Best For | Find/replace | Scripting, everywhere | Advanced text work | Complex transforms | Repo-wide rewrite | ## FAQ **Q: When should I still use sed?** A: For multi-line addressing, conditional logic, delete/print operations, or strict POSIX scripting. sd focuses on find/replace only. **Q: sd vs `ripgrep --replace`?** A: `rg --replace` shows you matches with replacements but doesn't write by default (you pipe to `sponge` or use `rg -r ... --files-with-matches | xargs sed ...`). sd writes in-place cleanly. Use rg to preview matches, sd to apply changes. **Q: Does it respect .gitignore?** A: Not natively. Combine with `rg --files -l` to get the list of files first, then pipe to sd. **Q: Safe to use with large files?** A: Yes — it streams input, not loads the whole file. In-place edits use a temp file + atomic rename so crashes don't corrupt your data. ## Sources - GitHub: https://github.com/chmln/sd - License: MIT --- Source: https://tokrepo.com/en/workflows/8f2991f3-3814-11f1-9bc6-00163e2b0d79 Author: Script Depot