Stream editing and text substitution are daily necessities for Linux developers and system administrators. For decades, the standard tool for find-and-replace tasks across files and terminal pipelines has been the classic Unix utility sed. While powerful, sed suffers from frustrating historical quirks: arcane syntax rules (such as s/find/replace/g), confusing escape requirements for forward slashes and parentheses, and notorious cross-platform differences between GNU sed on Linux and BSD sed on macOS when performing in-place edits (-i vs -i '').
sd is an intuitive, modern replacement for sed written in Rust. It does away with arcane delimiters, accepts standard modern regular expressions powered by Rust’s high-speed regex engine, makes in-place file modifications safe and consistent across operating systems, and handles literal string replacements without escaping forward slashes or quotes.
Why sd Is Superior to Traditional sed
The design philosophy of sd prioritises simplicity, performance, and developer ergonomics:
- Intuitive Positional Syntax: Instead of typing
sed -i 's/foo/bar/g' file.txt, sd uses simple positional arguments:sd 'foo' 'bar' file.txt. - No Delimiter Escaping: When replacing URLs, Unix file paths, or HTML tags (e.g. replacing
/usr/local/binwith/usr/bin), you never need to escape forward slashes or switch to awkward delimiters likes|...|...|g. - Modern Regex Support: sd uses standard PCRE-style regex syntax out of the box, including capture groups (
$1,$2), word boundaries (\b), and lookahead patterns without requiring obscure-Eor-rflags. - Safe In-Place Editing: Unlike sed, which writes to standard output by default and requires the
-iflag to modify files, passing a file argument to sd modifies the file directly and atomically without temporary file leftovers. - Rust Speed: Built on the high-performance Rust regex engine, sd processes gigabyte-scale log files significantly faster than traditional sed implementations.
Installing sd on Linux
sd is packaged across major Linux package managers and via Cargo.
Installing on Arch Linux and Manjaro
On Arch-based distributions, install sd from the official repositories:
sudo pacman -S sd
Installing on Ubuntu, Debian, and Linux Mint
On modern Debian and Ubuntu releases (Ubuntu 22.04 LTS and later), install sd via APT:
sudo apt update
sudo apt install sd
Installing via Cargo
To compile and install the latest upstream release using Cargo:
cargo install sd
Basic String Replacements with sd
The basic invocation structure of sd follows a natural pattern:
sd 'search_pattern' 'replacement_string' [file]
Replacing Text Directly Inside a File
Suppose you have an Nginx configuration file where you need to change a domain name:
sd 'staging.example.com' 'production.example.com' /etc/nginx/sites-available/default
sd replaces every occurrence across the file in-place immediately. You do not need to supply a -i or -g flag; global in-place substitution is the sensible default.
Replacing File Paths Without Escaping
Replacing file paths in sed requires tedious “leaning toothpick syndrome” (e.g. sed 's/\/var\/www\/html/\/var\/www\/public/g'). With sd, simply quote the strings naturally:
sd '/var/www/html' '/var/www/public' config.php
Because sd does not use slashes as syntax delimiters, forward slashes are evaluated literally.
Using sd in Terminal Pipelines
If you omit the file argument, sd reads from standard input (stdin) and outputs to standard output (stdout), making it a drop-in replacement for sed inside shell pipelines:
echo "The price is $50 USD" | sd '\$50' '£40'
The terminal outputs: The price is £40 USD.
Advanced Pattern Matching with Regular Expressions
sd fully supports modern regular expressions, including capture groups and character classes.
Using Regex Capture Groups
To capture portions of a string and reorder them in the output, use numbered capture groups ($1, $2):
# Convert dates from YYYY-MM-DD to DD-MM-YYYY format
sd '(\d{4})-(\d{2})-(\d{2})' '$3-$2-$1' reports.csv
Every date formatted like 2026-10-12 is instantaneously transformed into 12-10-2026.
Named Capture Groups
For complex scripts, sd supports named capture groups for improved code readability:
sd '(?P<first>\w+) (?P<last>\w+)' '$last, $first' authors.txt
Enforcing Fixed String Replacement (Literal Mode)
If your search pattern contains numerous special characters (such as brackets, asterisks, dots, or question marks) and you want to match them literally without escaping every character, use the -s (or --string-mode) flag:
sd -s 'function(a, b) { return a * b; }' 'const multiply = (a, b) => a * b;' script.js
Under string mode, every parenthesis, curly bracket, and asterisk is treated as pure literal text, completely disabling regex interpretation.
Syntax Comparison: sed vs sd
| Operation | Traditional sed Command | Modern sd Command |
|---|---|---|
| In-place file edit | sed -i 's/old/new/g' file.txt |
sd 'old' 'new' file.txt |
| Replace path strings | sed -i 's|\/app\/v1|\/app\/v2|g' config |
sd '/app/v1' '/app/v2' config |
| Regex capture groups | sed -E 's/([0-9]+)px/\1rem/g' style.css |
sd '(\d+)px' '$1rem' style.css |
| Literal text matching | Requires manual escaping of all symbols. | sd -s 'calc(100% - 20px)' '80vw' style.css |
By eliminating archaic syntax rules and embracing modern regex standards, sd streamlines text manipulation on Linux and allows you to execute find-and-replace operations with speed and confidence.