Terminal GuideTerminal Guide
sd icon

sd

Modern CLI
macOSLinuxWindows
Rust

Intuitive find & replace CLI (sed alternative).

Official Website

Features

Intuitive SyntaxRegex SupportPreview ModeFast
Replaces
sed

Installation

Homebrew
brew install sd
Pacman (Arch)
pacman -S sd
Cargo (Rust)
cargo install sd

Why use sd?

sd eliminates the complex syntax of sed, providing an intuitive and easy-to-remember modern tool for string replacement.

Intuitive Syntax

No complex escaping like sed. Use slashes and other special characters directly.

Regex Support

Full support for powerful regex features like capture groups and lookahead/lookbehind.

Preview Mode

Preview changes before executing. Prevent unintended replacements and work safely.

Fast Processing

Built in Rust for high speed. Process large files and quantities without stress.

Basic Usage

Basic Syntax

Basic Commands
# Basic form: sd 'search pattern' 'replacement string' file
sd 'hello' 'world' file.txt

# Replace from standard input
echo 'hello world' | sd 'world' 'universe'

# Batch replace multiple files
sd 'old' 'new' *.txt

Syntax Comparison with sed

Differences between sed and sd
# sed: requires delimiters and escaping
sed -i 's/hello/world/g' file.txt
sed -i 's/path\/to\/file/new\/path/g' file.txt

# sd: simple and intuitive
sd 'hello' 'world' file.txt
sd 'path/to/file' 'new/path' file.txt  # No escaping slashes needed!

Common Options

OptionDescriptionExample
-pPreview mode (display changes only)sd -p 'foo' 'bar' file.txt
-sTreat as literal string (disable regex)sd -s '.*' 'literal' file.txt
-fSpecify flags (i: case insensitive, m: multiline)sd -f i 'hello' 'HELLO' file.txt
-nReplace only first N matchessd -n 1 'foo' 'bar' file.txt

Regex Patterns

Capture Groups

Using Capture Groups
# Capture with parentheses, reference with $1, $2
sd '(\w+)@(\w+)' '$2:$1' file.txt
# user@domain → domain:user

# Named capture groups
sd '(?P<name>\w+)@(?P<domain>\w+)' '$domain:$name' file.txt

# Convert date format
sd '(\d{4})-(\d{2})-(\d{2})' '$2/$3/$1' dates.txt
# 2024-01-15 → 01/15/2024

Lookahead and Lookbehind

Lookahead/Lookbehind Patterns
# Positive lookahead: replace text before specific pattern
sd 'foo(?=bar)' 'baz' file.txt
# foobar → bazbar, foobaz → foobaz (no change)

# Positive lookbehind: replace text after specific pattern
sd '(?<=foo)bar' 'baz' file.txt
# foobar → foobaz

# Negative lookahead: replace only if not followed by specific pattern
sd 'foo(?!bar)' 'baz' file.txt

Common Regex Patterns

Practical Patterns
# Start and end of line
sd '^prefix' 'new_prefix' file.txt  # Replace prefix at line start
sd 'suffix$' 'new_suffix' file.txt  # Replace suffix at line end

# Whitespace handling
sd '\s+' ' ' file.txt              # Multiple spaces to single space
sd '^\s+' '' file.txt              # Remove leading whitespace
sd '\s+$' '' file.txt              # Remove trailing whitespace

# Word boundaries
sd '\bword\b' 'replacement' file.txt  # Replace whole word only

Practical Examples

Direct File Editing

File Editing
# Edit single file directly
sd 'old_function' 'new_function' src/main.rs

# Batch edit multiple files
sd 'deprecated_api' 'new_api' src/*.js

# Recursive replacement with find
fd -e py | xargs sd 'print(' 'logger.info('

# Replace only files managed by git
git ls-files '*.ts' | xargs sd 'oldName' 'newName'

Using with Pipes

Pipeline Integration
# Format JSON and replace values
cat config.json | sd '"debug": true' '"debug": false'

# Process log files
cat app.log | sd '\[(\d+)\]' 'PID:$1' | less

# Expand environment variables
cat template.env | sd '\$\{HOME\}' "$HOME"

# Change CSV column order
cat data.csv | sd '^([^,]+),([^,]+),(.+)$' '$2,$1,$3'

Code Fixing Examples

Code Refactoring
# Rename function in bulk
sd 'getUserById' 'fetchUserById' src/**/*.ts

# Rewrite import statements
sd "from 'lodash'" "from 'lodash-es'" src/*.js

# Add variable type annotations
sd 'const (\w+) = ' 'const $1: string = ' file.ts

# Remove console.log
sd 'console\.log\([^)]*\);?\n?' '' src/*.js

# Update old React syntax to new format
sd 'React\.FC<(.+)>' 'FC<$1>' components/*.tsx

Comparison with sed

Operationsedsd
Basic replacementsed 's/foo/bar/g'sd 'foo' 'bar'
Replacement with slashessed 's/a\\/b/c\\/d/g'sd 'a/b' 'c/d'
Direct file editingsed -i 's/foo/bar/g' filesd 'foo' 'bar' file
Capture groupssed 's/\\(.*\\)/[\\1]/g'sd '(.*)' '[$1]'
Case insensitivesed 's/foo/bar/gi'sd -f i 'foo' 'bar'
Replacement with newlinesComplex command neededsd 'foo\\nbar' 'baz'

Detailed Comparison Examples

sed vs sd Detailed Comparison
# 1. URL path replacement
# sed (escaping nightmare)
sed 's/https:\/\/example\.com\/api\/v1/https:\/\/example\.com\/api\/v2/g' file
# sd (write as-is)
sd 'https://example.com/api/v1' 'https://example.com/api/v2' file

# 2. JSON value replacement
# sed
sed 's/"version": "[0-9]*\.[0-9]*\.[0-9]*"/"version": "2.0.0"/g' package.json
# sd
sd '"version": "[0-9]+\.[0-9]+\.[0-9]+"' '"version": "2.0.0"' package.json

# 3. Multi-line patterns
# sed (very complex)
sed -z 's/foo\nbar/baz/g' file
# sd (intuitive)
sd 'foo\nbar' 'baz' file

Tips and Tricks

  • Always use preview mode (-p) to confirm results before replacement. Especially important with regex
  • Use -s option to treat as literal string. Search for regex metacharacters like .* literally
  • Combine with fd or rg to efficiently process only files matching specific criteria
  • Before doing large-scale replacements in Git repos, use git stash or create a new branch to work safely
  • Be careful with shell quoting. Use single quotes (') to prevent shell expansion
  • sd is written in Rust, so you can also install it easily with cargo install sd
Written by Dai AokiPublished: 2026-01-20

Related Articles

Explore More