Skip to content

sd - Intuitive Find & Replace CLI Cheatsheet

sd - Intuitive Find & Replace CLI Cheatsheet

sd is a fast find-and-replace command-line tool written in Rust, designed to make the common case simple. Where sed has cryptic syntax, fragile escaping, and BSD/GNU differences, sd uses straightforward regex (or literal strings), obvious capture-group references ($1), and reads/writes files safely. For the everyday “replace X with Y across these files” task, it is far easier to get right than sed.

Installation

PlatformCommand
Cargo (all platforms)cargo install sd
macOS (Homebrew)brew install sd
Arch Linuxsudo pacman -S sd
Debian/Ubuntusudo apt install sd
Fedorasudo dnf install sd
Verifysd --version

Basic Usage

sd reads stdin or files. The form is sd FIND REPLACE [FILES...].

CommandDescription
`echo “hello”sd hello world`
sd 'before' 'after' file.txtReplace in a file (in place)
sd 'before' 'after' *.txtReplace across many files
sd --helpFull option list

Literal vs Regex

CommandBehavior
sd 'a.b' 'X' fileRegex: . matches any char
sd -s 'a.b' 'X' fileLiteral string (-s/--string-mode)
sd '\d+' 'N' fileRegex digit class

Use -s when your search text contains regex metacharacters you want treated literally — no manual escaping.

Capture Groups

sd uses simple $1, $2 references (or ${1} when adjacent to text).

# Swap "First Last" → "Last, First"
echo "Ada Lovelace" | sd '(\w+) (\w+)' '$2, $1'
# → Lovelace, Ada

# Reformat dates YYYY-MM-DD → DD/MM/YYYY
sd '(\d{4})-(\d{2})-(\d{2})' '$3/$2/$1' dates.txt

# Use braces when the group is followed by digits/letters
echo "v2" | sd 'v(\d)' 'version${1}0'   # → version20

Key Options

OptionDescription
-s, --string-modeTreat FIND/REPLACE as literal strings
-p, --previewShow the diff/result without writing
-f, --flags FLAGSRegex flags: i (case-insensitive), m, s, etc.
-n, --max-replacements NLimit number of replacements
stdin/stdoutOmit files to act as a filter

Regex Flags (-f)

FlagEffect
iCase-insensitive
mMultiline (^/$ match line boundaries)
sDot matches newlines
wMatch whole words
# Case-insensitive replace
sd -f i 'error' 'ERROR' log.txt

Safe Preview

# See what WOULD change before touching files
sd -p 'foo' 'bar' src/*.rs

# Then apply
sd 'foo' 'bar' src/*.rs

Common Workflows

# Rename a symbol across a codebase (preview first)
sd -p 'oldFunctionName' 'newFunctionName' **/*.js
sd 'oldFunctionName' 'newFunctionName' **/*.js

# Strip trailing whitespace
sd ' +$' '' file.txt

# Replace a literal path (string mode avoids escaping the dots/slashes)
sd -s './old/path.js' './new/path.js' config.json

# Pipe usage in a chain
cat access.log | sd '\d+\.\d+\.\d+\.\d+' '[REDACTED_IP]'

sd vs sed

Aspectsdsed
SyntaxSimple, modern regexTerse, historical
Capture refs$1, $2\1, \2
Literal mode-s (no escaping)Manual escaping
In-placeDefault for files-i (BSD/GNU differ)
Streaming edits (sed-style)Focused on replaceFull stream editor

sd is a focused find-and-replace; for stream editing beyond substitution, sed/awk still apply. For search (not replace), pair with ripgrep.

Resources