Modern find-and-replace using sd (simpler than sed) and batch replacement patterns.
This skill inherits all available tools. When active, it can use any tool Claude has access to.
Modern find-and-replace using sd (simpler than sed) and batch replacement patterns.
sd, find replace, batch replace, sed replacement, string replacement, rename
# Replace in file (in-place)
sd 'oldText' 'newText' file.txt
# Replace in multiple files
sd 'oldText' 'newText' *.js
# Preview without changing (pipe instead of file)
cat file.txt | sd 'old' 'new'
| sed | sd | Notes |
|---|---|---|
sed 's/old/new/g' | sd 'old' 'new' | Global by default |
sed -i 's/old/new/g' | sd 'old' 'new' file | In-place by default |
sed 's/\./dot/g' | sd '\.' 'dot' | Same escaping |
sed 's#path/to#new/path#g' | sd 'path/to' 'new/path' | No delimiter issues |
# Rename variable across files
sd 'oldVarName' 'newVarName' src/**/*.ts
# Preview first with rg
rg 'oldVarName' src/
# Then apply
sd 'oldVarName' 'newVarName' $(rg -l 'oldVarName' src/)
# Rename function (all usages)
sd 'getUserData' 'fetchUserProfile' src/**/*.ts
# More precise with word boundaries
sd '\bgetUserData\b' 'fetchUserProfile' src/**/*.ts
# Update import paths
sd "from '../utils'" "from '@/utils'" src/**/*.ts
sd "require\('./config'\)" "require('@/config')" src/**/*.js
# Single to double quotes
sd "'" '"' file.json
# Template literals
sd '"\$\{(\w+)\}"' '`${$1}`' src/**/*.ts
# Reorder parts
sd '(\w+)@(\w+)\.com' '$2/$1' emails.txt
# john@example.com → example/john
# Wrap in function
sd 'console\.log\((.*)\)' 'logger.info($1)' src/**/*.js
# Handle optional whitespace
sd 'function\s*\(' 'const fn = (' src/**/*.js
# Replace across lines
sd -s 'start\n.*\nend' 'replacement' file.txt
# 1. Find files with pattern
rg -l 'oldPattern' src/
# 2. Preview replacements
rg 'oldPattern' -r 'newPattern' src/
# 3. Apply to found files
sd 'oldPattern' 'newPattern' $(rg -l 'oldPattern' src/)
# Replace in specific file types
fd -e ts -x sd 'old' 'new' {}
# Replace in files matching name pattern
fd 'config' -e json -x sd '"dev"' '"prod"' {}
# Safe workflow: preview → verify → apply
# Step 1: List affected files
rg -l 'oldText' src/
# Step 2: Show what will change
rg 'oldText' -r 'newText' src/
# Step 3: Apply (only after verification)
sd 'oldText' 'newText' $(rg -l 'oldText' src/)
# Step 4: Verify
rg 'oldText' src/ # Should return nothing
git diff # Review changes
# Literal dot
sd '\.' ',' file.txt
# Literal brackets
sd '\[' '(' file.txt
# Literal dollar sign
sd '\$' '€' file.txt
# Literal backslash
sd '\\' '/' paths.txt
| Character | Escape |
|---|---|
. | \. |
* | \* |
? | \? |
[ ] | \[ \] |
( ) | \( \) |
{ } | \{ \} |
$ | \$ |
^ | \^ |
\ | \\ |
sd '"version": "\d+\.\d+\.\d+"' '"version": "2.0.0"' package.json
sd "from '(\./[^']+)'" "from '\$1.js'" src/**/*.ts
# kebab-case to camelCase (simple cases)
sd 'class="(\w+)-(\w+)"' 'className="$1$2"' src/**/*.jsx
sd '/api/v1/' '/api/v2/' src/**/*.ts
sd 'api\.example\.com' 'api.newdomain.com' src/**/*.ts
# Remove entire console.log statements
sd 'console\.log\([^)]*\);?\n?' '' src/**/*.ts
sd 'id="(\w+)"' 'id="prefix-$1"' src/**/*.html
| Tip | Why |
|---|---|
Always preview with rg -r first | Avoid accidental mass changes |
Use git diff after | Verify changes before commit |
| Prefer specific patterns | \bword\b over word to avoid partial matches |
| Quote patterns | Avoid shell interpretation |
| Use fd to target files | More precise than **/*.ext |
# Cargo (Rust)
cargo install sd
# Homebrew (macOS)
brew install sd
# Windows (scoop)
scoop install sd