sd - Intuitives Find & Replace CLI-Spickzettel
sd ist ein schnelles Find-and-Replace-Command-Line-Tool, geschrieben in Rust, mit dem Ziel, den häufigen Fall einfach zu machen. Wo sed kryptische Syntax, fragile Escaping und BSD/GNU-Unterschiede hat, verwendet sd unkomplizierte Regex (oder Literal-Strings), offensichtliche Capture-Group-Referenzen ($1) und liest/schreibt Dateien sicher. Für die alltägliche “ersetze X mit Y über diese Dateien”-Aufgabe ist es viel einfacher, recht zu machen als sed.
Installation
| Plattform | Befehl |
|---|
| Cargo (alle Plattformen) | 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 |
| Verifizieren | sd --version |
Grundlegende Nutzung
sd liest Stdin oder Dateien. Das Form ist sd FIND REPLACE [FILES...].
| Befehl | Beschreibung |
|---|
| `echo “hello” | sd hello world` |
sd 'before' 'after' file.txt | Ersetze in einer Datei (in place) |
sd 'before' 'after' *.txt | Ersetze über viele Dateien |
sd --help | Vollständige Optionsliste |
Literal vs Regex
| Befehl | Verhalten |
|---|
sd 'a.b' 'X' file | Regex: . Passt jedes Zeichen |
sd -s 'a.b' 'X' file | Literal-String (-s/--string-mode) |
sd '\d+' 'N' file | Regex-Digit-Klasse |
Verwende -s, wenn dein Suchtext Regex-Metazeichen enthält, die du literal behandeln möchtest — keine manuelle Escaping.
Capture-Gruppen
sd verwendet einfache $1, $2-Referenzen (oder ${1} wenn angrenzend an Text).
# Vertausche "First Last" → "Last, First"
echo "Ada Lovelace" | sd '(\w+) (\w+)' '$2, $1'
# → Lovelace, Ada
# Dates neu formatieren YYYY-MM-DD → DD/MM/YYYY
sd '(\d{4})-(\d{2})-(\d{2})' '$3/$2/$1' dates.txt
# Verwende Geschweifte Klammern, wenn die Gruppe von Ziffern/Buchstaben gefolgt wird
echo "v2" | sd 'v(\d)' 'version${1}0' # → version20
Wichtige Optionen
| Option | Beschreibung |
|---|
-s, --string-mode | Behandle FIND/REPLACE als Literal-Strings |
-p, --preview | Zeige die Diff/Ergebnis ohne zu schreiben |
-f, --flags FLAGS | Regex-Flags: i (case-insensitiv), m, s, usw. |
-n, --max-replacements N | Limite Anzahl der Replacements |
| stdin/stdout | Omit-Dateien zum Handeln als Filter |
Regex-Flags (-f)
| Flag | Effekt |
|---|
i | Case-insensitiv |
m | Multiline (^/$ Match-Zeilen-Grenzen) |
s | Punkt Matches Newlines |
w | Ganzes Wort Match |
# Case-insensitiver Replace
sd -f i 'error' 'ERROR' log.txt
Sicherer Preview
# Sehe, was sich WÜRDE ändern, bevor du Dateien berührst
sd -p 'foo' 'bar' src/*.rs
# Dann wenden an
sd 'foo' 'bar' src/*.rs
Häufige Workflows
# Umbenennung eines Symbols über a Codebase (Preview first)
sd -p 'oldFunctionName' 'newFunctionName' **/*.js
sd 'oldFunctionName' 'newFunctionName' **/*.js
# Strip trailing whitespace
sd ' +$' '' file.txt
# Ersetze einen Literal-Pfad (String-Modus vermeidet Escaping die Punkte/Slashes)
sd -s './old/path.js' './new/path.js' config.json
# Pipe-Nutzung in einer Kette
cat access.log | sd '\d+\.\d+\.\d+\.\d+' '[REDACTED_IP]'
sd vs sed
| Aspekt | sd | sed |
|---|
| Syntax | Einfach, moderne Regex | Terse, historisch |
| Capture-Referenzen | $1, $2 | \1, \2 |
| Literal-Modus | -s (kein Escaping) | Manuelles Escaping |
| In-Place | Standard für Dateien | -i (BSD/GNU differ) |
| Streaming-Edits (sed-style) | Fokussiert auf Replace | Vollständiger Stream-Editor |
sd ist ein fokussierter Find-and-Replace; für Stream-Editing über Substitution hinaus, gelten sed/awk immer noch. Zur Suche (nicht Replace), Paar mit ripgrep.
Ressourcen