| Crates.io | esed |
| lib.rs | esed |
| version | 1.1.14 |
| created_at | 2025-11-15 04:25:23.347197+00 |
| updated_at | 2026-01-22 08:18:47.678551+00 |
| description | Easy sed |
| homepage | |
| repository | https://github.com/pepa65/esed |
| max_upload_size | |
| id | 1933995 |
| size | 46,766 |
Easy sed
Why use it over any existing tools?
esed uses Rust regex syntax that is very feature-rich.
Forget about dealing with quirks of sed or awk and get productive immediately.-i/--in-place to modify files - Defaults to output to stdout for safety.sedWhile sed does a whole lot more, esed focuses on doing just one thing and doing it well.
Here are some cherry-picked examples where esed shines:
esed SEARCH REPLACEMENTsed s/SEARCH/REPLACEMENT/gesed '\n' ', 'sed ':a;N;$!ba;s/\n/, /g'echo "Example with /path/, etc." |esed '.*(/.*/)' '$1'echo "Example with /path/, etc." |sed -E 's/.*(\\/.*\\/)/\1/g'sed with a different delimiter (still messy): echo "Example with /path/ etc." |sed -E 's@.*(/.*/)@\1@g'esed -i SEARCH REPLACEMENT FILEsed -i -e 's/SEARCH/REPLACEMENT/g' FILE (some platforms do not need the -e)esed -i SEARCH REPLACEMENT FILE* XFILE STHFILEfor file in FILE* XFILE STHFILE; do sed -i -e 's/SEARCH/REPLACEMENT/g' "$file"; done^ #, dot . wildcard (unicode) character matching,
character class matching between square brackets [ ] and character exclusion between [^ and ].*: 0 or more, +: 1 or more, ?: 0 or 1, {n,m}: between n and m times| matches either the pattern on the left or the right.. * & $) by prefixing with \\. In REPLACEMENT use $$ to escape $.\s: whitespace, \S: non-whitespace, \d: digit, \pL: letter (any unicode class)
\n: newline, \r: carriagereturn, \t: tab(?-u: and )( ) enables capturing patterns in the replacement and combining/grouping.(?P<NAME> and ).hyperfine --warmup 3 --export-markdown out.md \
'sed -E "s/\"/'"'"'/g" *.json >/dev/null' \
'sed "s/\"/'"'"'/g" *.json >/dev/null' \
'esed -i "\"" "'"'"'" *.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 |
esed "\"" "'" *.json > /dev/null |
0.997 ± 0.006 | 0.987…1.007 |
Result: ~2.35 times faster
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' \
'esed "(\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.1.4…11.725 |
sed "s:\(\w\+\):\1\1:g" dump.json >/dev/null |
11.239 ± 0.208 | 11.057…11.762 |
esed "(\w+)" "$1$1" dump.json >/dev/null |
0.942 ± 0.004 | 0.936…0.951 |
Result: ~11.93 times faster
wget https://github.com/pepa65/esed/releases/download/1.1.14/esed
sudo mv esed /usr/local/bin
sudo chown root:root /usr/local/bin/esed
sudo chmod +x /usr/local/bin/esed
If not installed yet, install a Rust toolchain, see https://www.rust-lang.org/tools/install
The binary esed will be installed into ~/.cargo/bin/ (might need to be added to PATH!)
cargo install esed
cargo install --git https://github.com/pepa65/esed
git clone https://github.com/pepa65/esed
cd esed
rustup target add x86_64-unknown-linux-musl
cargo inst # Alias defined in .cargo/config.toml
Even without a full Rust toolchain, rust binaries can be installed with the static binary cargo-binstall:
# Install cargo-binstall for Linux x86_64
# (Other versions are available at https://crates.io/crates/cargo-binstall)
wget github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz
tar xf cargo-binstall-x86_64-unknown-linux-musl.tgz
sudo chown root:root cargo-binstall
sudo mv cargo-binstall /usr/local/bin/
Only a linux-x86_64 (musl) binary available: cargo-binstall esed
This will also be installed into ~/.cargo/bin/ and might need to be added to PATH!
-s/--strings to disable regex.
# Remove string with special characters
echo 'lots((([]))) of special chars' |esed -s '((([])))' ''
# Result: "lots of special chars"
# Trim whitespace before the end of input
echo 'lorem ipsum 23 ' |esed '\s+$' ''
# Result: "lorem ipsum 23"
echo 'cargo +nightly watch' |esed '(\w+)\s+\+(\w+)\s+(\w+)' 'cmd: $1, channel: $2, subcmd: $3'
# Result: "cmd: cargo, channel: nightly, subcmd: watch"
echo "123.45" |esed '(?P<dollars>\d+)\.(?P<cents>\d+)' '$dollars dollars and $cents cents'
# Result: 123 dollars and 45 cents
If stumbling upon ambiguities, use ${var} instead of $var, like:
echo '123.45' |esed '(?P<dollars>\d+)\.(?P<cents>\d+)' '${dollars}_dollars and ${cents}_cents'
# Result: "123_dollars and 45_cents"
esed -i 'window.fetch' 'fetch' http.js
To preview changes (the -i/--in-place flag needs to be given to modify files):
esed 'window.fetch' 'fetch' http.js
esed 'from "react"' 'from "preact"' ../*/*.json
esed v1.1.14 - Easy sed
Usage: esed [OPTIONS] <SEARCH> <REPLACEMENT> [FILE]...
Arguments:
<SEARCH> SEARCH: regexp or (if using '-s'/'--strings') string
<REPLACEMENT> REPLACEMENT (regex captured values like $1 can be used)
[FILE]... Optional path(s) to file(s)
Options:
-i, --in-place Modify file(s) in-place instead of output to stdout
-s, --strings Treat SEARCH and REPLACEMENT as literal strings [default: regex]
-c, --case-insensitive Use regex case-insensitive [default: case-sensitive]
-w, --word Match the SEARCH regex as a full word [default: match anywhere]
-d, --dot-match-newline Dots also match newlines [default: newlines not matched by dots]
-n, --no-multiline No multiline: '^' and '$' anchor only to the very beginning and end [default: multiline]
-l, --limit <MAX> Limit the number of replacements per file (0: unlimited) [default: 0]
-h, --help Print help
-V, --version Print version