sd - Cheatsheet Intuitive Find & Replace CLI
sd è uno strumento find-and-replace da command-line veloce scritto in Rust, progettato per rendere il caso comune semplice. Dove sed ha una sintassi criptica, escaping fragile, e differenze BSD/GNU, sd usa regex schietto (o literal string), ovvie riferimenti a capture-group ($1), e legge/scrive file in sicurezza. Per il quotidiano “sostituisci X con Y in questi file” task, è molto più facile da ottenere corretto che sed.
Installazione
| Piattaforma | Comando |
|---|
| Cargo (tutte piattaforme) | cargo install sd |
| macOS (Homebrew) | brew install sd |
| Arch Linux | sudo pacman -S sd |
| Debian/Ubuntu | sudo apt install sd |
| Fedora | sudo dnf install sd |
| Verifica | sd --version |
Utilizzo di Base
sd legge stdin o file. La forma è sd FIND REPLACE [FILES...].
| Comando | Descrizione |
|---|
| `echo “hello” | sd hello world` |
sd ''before'' ''after'' file.txt | Sostituisci in un file (in place) |
sd ''before'' ''after'' *.txt | Sostituisci across molti file |
sd --help | Lista opzione completa |
Literal vs Regex
| Comando | Comportamento |
|---|
sd ''a.b'' ''X'' file | Regex: . corrisponde a any char |
sd -s ''a.b'' ''X'' file | Literal string (-s/--string-mode) |
sd ''\d+'' ''N'' file | Regex digit class |
Usa -s quando il tuo testo di ricerca contiene metacharacter regex che vuoi trattati letteralmente — nessun escaping manuale.
Capture Groups
sd usa semplici riferimenti $1, $2 (o ${1} quando adiacente al testo).
# Scambia "First Last" → "Last, First"
echo "Ada Lovelace" | sd '(\w+) (\w+)' '$2, $1'
# → Lovelace, Ada
# Riformatta date YYYY-MM-DD → DD/MM/YYYY
sd '(\d{4})-(\d{2})-(\d{2})' '$3/$2/$1' dates.txt
# Usa brace quando il group è seguito da digits/letters
echo "v2" | sd ''v(\d)'' ''version${1}0'' # → version20
Opzioni Chiave
| Opzione | Descrizione |
|---|
-s, --string-mode | Tratta FIND/REPLACE come literal string |
-p, --preview | Mostra la diff/risultato senza scrivere |
-f, --flags FLAGS | Regex flags: i (case-insensitive), m, s, etc. |
-n, --max-replacements N | Limita numero di replacements |
| stdin/stdout | Ometti file per agire come un filter |
Regex Flags (-f)
| Flag | Effetto |
|---|
i | Case-insensitive |
m | Multiline (^/$ match line boundaries) |
s | Dot corrisponde a newline |
w | Match whole words |
# Case-insensitive replace
sd -f i ''error'' ''ERROR'' log.txt
Safe Preview
# Vedi cosa CAMBIEREBBE prima di toccare i file
sd -p ''foo'' ''bar'' src/*.rs
# Poi applica
sd ''foo'' ''bar'' src/*.rs
Workflow Comuni
# Rinomina un simbolo attraverso una codebase (preview prima)
sd -p ''oldFunctionName'' ''newFunctionName'' **/*.js
sd ''oldFunctionName'' ''newFunctionName'' **/*.js
# Rimuovi trailing whitespace
sd '' +$'' '''' file.txt
# Sostituisci un literal path (string mode evita escaping i dots/slashes)
sd -s ''./old/path.js'' ''./new/path.js'' config.json
# Pipe usage in una chain
cat access.log | sd ''\d+\.\d+\.\d+\.\d+'' ''[REDACTED_IP]''
sd vs sed
| Aspetto | sd | sed |
|---|
| Syntax | Simple, modern regex | Terse, historical |
| Capture refs | $1, $2 | \1, \2 |
| Literal mode | -s (nessun escaping) | Manual escaping |
| In-place | Default per file | -i (BSD/GNU differiscono) |
| Streaming edits (sed-style) | Focused on replace | Full stream editor |
sd è un focused find-and-replace; per stream editing oltre substitution, sed/awk ancora si applicano. Per ricerca (non replace), pair con ripgrep.
Risorse