Top Related Projects
:cherry_blossom: A command-line fuzzy finder
A simple, fast and user-friendly alternative to 'find'
ripgrep recursively searches directories for a regex pattern while respecting your gitignore
A code-searching tool similar to ack, but faster.
An interactive cheatsheet tool for the command-line
:mag: A simple, fast fuzzy finder for the terminal
Quick Overview
sd (short for "sed") is a modern, intuitive alternative to the classic Unix sed command. It's designed to be easier to use and more powerful for common text manipulation tasks, with a focus on simplicity and efficiency.
Pros
- Intuitive syntax that's easier to understand and use compared to sed
- Supports extended regular expressions by default
- Faster performance for many operations compared to sed
- Cross-platform compatibility (works on Unix-like systems and Windows)
Cons
- Not a drop-in replacement for sed in all scenarios
- May require learning a new syntax for users already familiar with sed
- Less widespread adoption compared to the ubiquitous sed
Code Examples
- Simple text replacement:
echo 'Hello, World!' | sd 'World' 'Universe'
# Output: Hello, Universe!
- Using regular expressions:
echo 'The quick brown fox' | sd '\w+$' 'dog'
# Output: The quick brown dog
- In-place file editing:
sd -i 'old_text' 'new_text' file.txt
- Multiple replacements in one command:
echo 'apple banana cherry' | sd '(apple|cherry)' 'fruit'
# Output: fruit banana fruit
Getting Started
To install sd, you can use various package managers:
# On macOS using Homebrew
brew install sd
# On Arch Linux
pacman -S sd
# On other systems, you can download the binary from the GitHub releases page
# or build from source using Rust's cargo:
cargo install sd
After installation, you can start using sd in your terminal:
sd 'pattern' 'replacement' input_file
# or
echo 'input text' | sd 'pattern' 'replacement'
For more advanced usage and options, refer to the project's README or run sd --help
.
Competitor Comparisons
:cherry_blossom: A command-line fuzzy finder
Pros of fzf
- More versatile: fzf is a general-purpose fuzzy finder, useful for various tasks beyond text manipulation
- Interactive interface: Provides a real-time, interactive selection process
- Extensive integration: Works with many tools and has plugins for popular editors
Cons of fzf
- Learning curve: More complex to use for simple find-and-replace operations
- Resource usage: Can be more resource-intensive for large datasets
- Overkill: May be unnecessary for straightforward text substitutions
Code comparison
sd:
sd 'pattern' 'replacement' file.txt
fzf:
cat file.txt | fzf --multi | xargs -I {} sed -i 's/pattern/replacement/g' {}
While sd provides a simpler, more direct approach for find-and-replace operations, fzf offers a more interactive and flexible selection process that can be combined with other tools for similar results. sd is generally more efficient for straightforward text substitutions, while fzf excels in scenarios requiring more complex filtering and selection before manipulation.
A simple, fast and user-friendly alternative to 'find'
Pros of fd
- Written in Rust, offering better performance and memory safety
- More feature-rich, including colorized output and regex support
- Actively maintained with frequent updates and improvements
Cons of fd
- Larger binary size due to Rust compilation
- May have a steeper learning curve for users familiar with traditional Unix tools
Code Comparison
fd:
let walker = WalkBuilder::new(root)
.hidden(false)
.ignore(false)
.git_global(false)
.git_ignore(false)
.git_exclude(false)
.build();
sd:
let mut finder = Finder::new();
finder.ignore_hidden(false);
finder.ignore_files(false);
finder.follow_symlinks(true);
Summary
fd is a modern alternative to the traditional find command, offering improved performance and additional features. It's written in Rust, which provides memory safety and speed benefits. However, it may have a larger binary size and a slightly steeper learning curve compared to sd.
sd, on the other hand, is a simpler tool focused on finding and replacing strings. It's more lightweight and may be easier for users familiar with sed-like syntax. However, it lacks some of the advanced features and performance optimizations found in fd.
Both tools have their strengths, and the choice between them depends on the specific use case and user preferences.
ripgrep recursively searches directories for a regex pattern while respecting your gitignore
Pros of ripgrep
- Faster performance for large-scale searches
- More advanced regex support and search options
- Better handling of binary files and large codebases
Cons of ripgrep
- More complex usage with numerous flags and options
- Primarily focused on searching, not in-place text replacement
Code comparison
ripgrep:
rg "pattern" /path/to/search
sd:
sd "old_pattern" "new_pattern" /path/to/files
Key differences
- ripgrep is optimized for searching, while sd specializes in find-and-replace operations
- sd offers a simpler syntax for text replacement, making it more user-friendly for quick edits
- ripgrep provides more comprehensive search capabilities, including file type filtering and gitignore support
Use cases
- Use ripgrep for fast, advanced searching across large codebases
- Choose sd for quick, intuitive find-and-replace operations in files or streams
Both tools have their strengths, and the choice depends on whether you prioritize searching (ripgrep) or text replacement (sd) functionality.
A code-searching tool similar to ack, but faster.
Pros of The Silver Searcher
- Faster search performance, especially for large codebases
- More mature project with wider adoption and community support
- Supports a broader range of file types and search options
Cons of The Silver Searcher
- Less intuitive syntax for complex search and replace operations
- Limited to searching and doesn't offer in-place file modifications
- Slower development cycle with less frequent updates
Code Comparison
The Silver Searcher (ag):
ag "pattern" /path/to/search
ag -l "pattern" /path/to/search | xargs sed -i 's/old/new/g'
sd:
sd "pattern" "replacement" /path/to/search/**/*
sd -i "pattern" "replacement" /path/to/search/**/*
The Silver Searcher focuses on fast searching, while sd provides a more streamlined approach to search and replace operations. The Silver Searcher requires additional tools like sed for file modifications, whereas sd offers built-in replacement functionality. sd's syntax is generally more intuitive for search and replace tasks, but The Silver Searcher provides more advanced search capabilities and options for fine-tuning searches across various file types.
An interactive cheatsheet tool for the command-line
Pros of navi
- Interactive and user-friendly CLI interface for browsing and searching commands
- Supports multiple languages and shells
- Allows for easy sharing and importing of cheatsheets
Cons of navi
- Requires more setup and configuration compared to sd
- May have a steeper learning curve for new users
- Focuses on command management rather than text manipulation
Code comparison
navi:
navi --query "git commit"
sd:
echo "old text" | sd 'old' 'new'
Summary
navi is a feature-rich interactive cheatsheet tool for the command-line, offering a comprehensive solution for managing and accessing commands across various languages and shells. It excels in providing a user-friendly interface for browsing and searching commands, making it ideal for users who frequently work with complex or hard-to-remember commands.
sd, on the other hand, is a simpler and more focused tool designed for efficient text manipulation and substitution. It offers a straightforward approach to find-and-replace operations, making it particularly useful for quick text transformations in scripts or command-line workflows.
While navi provides a more comprehensive command management solution, sd offers a lightweight and fast option for text manipulation tasks. The choice between the two depends on the specific needs of the user and the complexity of their command-line workflows.
:mag: A simple, fast fuzzy finder for the terminal
Pros of fzy
- Faster performance for fuzzy finding, especially on large datasets
- Designed specifically for fuzzy finding, with a focus on interactive use
- Simpler installation process (single binary)
Cons of fzy
- More limited in scope, focusing only on fuzzy finding
- Less flexible for complex text processing tasks
- Fewer configuration options and customization features
Code comparison
fzy:
score_t fuzzy_match(const char *needle, const char *haystack) {
if (!*needle)
return SCORE_MAX;
score_t score = 0;
const char *haystack_iter = haystack;
for (const char *needle_iter = needle; *needle_iter && *haystack_iter; ) {
// ... (simplified for brevity)
}
return score;
}
sd:
pub fn replace(text: &str, pattern: &str, replacement: &str) -> String {
let regex = Regex::new(pattern).unwrap();
regex.replace_all(text, replacement).into_owned()
}
Summary
fzy is a specialized tool for fuzzy finding, offering superior performance in that specific domain. sd, on the other hand, is a more versatile text processing tool with a broader range of capabilities. fzy excels in interactive use cases requiring quick fuzzy matching, while sd is better suited for complex text manipulation tasks and offers more customization options. The choice between the two depends on the specific requirements of the project and the primary use case.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
sd - s
earch & d
isplace
sd
is an intuitive find & replace CLI.
The Pitch
Why use it over any existing tools?
Painless regular expressions. sd
uses regex syntax that you already know from JavaScript and Python. Forget about dealing with quirks of sed
or awk
- get productive immediately.
String-literal mode. Non-regex find & replace. No more backslashes or remembering which characters are special and need to be escaped.
Easy to read, easy to write. Find & replace expressions are split up, which makes them easy to read and write. No more messing with unclosed and escaped slashes.
Smart, common-sense defaults. Defaults follow common sense and are tailored for typical daily use.
Comparison to sed
While sed does a whole lot more, sd focuses on doing just one thing and doing it well. Here are some cherry-picked examples where sd shines.
Simpler syntax for replacing all occurrences:
- sd:
sd before after
- sed:
sed s/before/after/g
Replace newlines with commas:
- sd:
sd '\n' ','
- sed:
sed ':a;N;$!ba;s/\n/,/g'
Extracting stuff out of strings containing slashes:
-
sd:
echo "sample with /path/" | sd '.*(/.*/)' '$1'
-
sed:
echo "sample with /path/" | sed -E 's/.*(\\/.*\\/)/\1/g'
With sed, you can make it better with a different delimiter, but it is still messy:
echo "sample with /path/" | sed -E 's|.*(/.*/)|\1|g'
In place modification of files:
-
sd:
sd before after file.txt
-
sed:
sed -i -e 's/before/after/g' file.txt
With sed, you need to remember to use
-e
or else some platforms will consider the next argument to be a backup suffix.
Benchmarks
Simple replacement on ~1.5 gigabytes of JSON
hyperfine --warmup 3 --export-markdown out.md \
'sed -E "s/\"/'"'"'/g" *.json > /dev/null' \
'sed "s/\"/'"'"'/g" *.json > /dev/null' \
'sd "\"" "'"'"'" *.json > /dev/null'
Command | Mean [s] | Minâ¦Max [s] |
---|---|---|
sed -E "s/\"/'/g" *.json > /dev/null | 2.338 ± 0.008 | 2.332â¦2.358 |
sed "s/\"/'/g" *.json > /dev/null | 2.365 ± 0.009 | 2.351â¦2.378 |
sd "\"" "'" *.json > /dev/null | 0.997 ± 0.006 | 0.987â¦1.007 |
Result: ~2.35 times faster
Regex replacement on a ~55M json file:
hyperfine --warmup 3 --export-markdown out.md \
'sed -E "s:(\w+):\1\1:g" dump.json > /dev/null' \
'sed "s:\(\w\+\):\1\1:g" dump.json > /dev/null' \
'sd "(\w+)" "$1$1" dump.json > /dev/null'
Command | Mean [s] | Minâ¦Max [s] |
---|---|---|
sed -E "s:(\w+):\1\1:g" dump.json > /dev/null | 11.315 ± 0.215 | 11.102â¦11.725 |
sed "s:\(\w\+\):\1\1:g" dump.json > /dev/null | 11.239 ± 0.208 | 11.057â¦11.762 |
sd "(\w+)" "$1$1" dump.json > /dev/null | 0.942 ± 0.004 | 0.936â¦0.951 |
Result: ~11.93 times faster
Installation
Install through
cargo
with
cargo install sd
, or through various package managers
Quick Guide
-
String-literal mode. By default, expressions are treated as regex. Use
-F
or--fixed-strings
to disable regex.> echo 'lots((([]))) of special chars' | sd -F '((([])))' '' lots of special chars
-
Basic regex use - let's trim some trailing whitespace
> echo 'lorem ipsum 23 ' | sd '\s+$' '' lorem ipsum 23
-
Capture groups
Indexed capture groups:
> echo 'cargo +nightly watch' | sd '(\w+)\s+\+(\w+)\s+(\w+)' 'cmd: $1, channel: $2, subcmd: $3' cmd: cargo, channel: nightly, subcmd: watch
Named capture groups:
> echo "123.45" | sd '(?P<dollars>\d+)\.(?P<cents>\d+)' '$dollars dollars and $cents cents' 123 dollars and 45 cents
In the unlikely case you stumble upon ambiguities, resolve them by using
${var}
instead of$var
. Here's an example:> echo '123.45' | sd '(?P<dollars>\d+)\.(?P<cents>\d+)' '$dollars_dollars and $cents_cents' and > echo '123.45' | sd '(?P<dollars>\d+)\.(?P<cents>\d+)' '${dollars}_dollars and ${cents}_cents' 123_dollars and 45_cents
-
Find & replace in a file
> sd 'window.fetch' 'fetch' http.js
That's it. The file is modified in-place.
To preview changes:
> sd -p 'window.fetch' 'fetch' http.js
-
Find & replace across project
This example uses fd.
Good ol' unix philosophy to the rescue.
fd --type file --exec sd 'from "react"' 'from "preact"'
Same, but with backups (consider version control).
fd --type file --exec cp {} {}.bk \; --exec sd 'from "react"' 'from "preact"'
Edge cases
sd will interpret every argument starting with -
as a (potentially unknown) flag.
The common convention of using --
to signal the end of flags is respected:
$ echo "./hello foo" | sd "foo" "-w"
error: Found argument '-w' which wasn't expected, or isn't valid in this context
USAGE:
sd [OPTIONS] <find> <replace-with> [files]...
For more information try --help
$ echo "./hello foo" | sd "foo" -- "-w"
./hello -w
$ echo "./hello --foo" | sd -- "--foo" "-w"
./hello -w
Escaping special characters
To escape the $
character, use $$
:
⯠echo "foo" | sd 'foo' '$$bar'
$bar
Top Related Projects
:cherry_blossom: A command-line fuzzy finder
A simple, fast and user-friendly alternative to 'find'
ripgrep recursively searches directories for a regex pattern while respecting your gitignore
A code-searching tool similar to ack, but faster.
An interactive cheatsheet tool for the command-line
:mag: A simple, fast fuzzy finder for the terminal
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot