What does it do?

Basically sad is a Batch File Edit tool.

It will show you a really nice diff of proposed changes before you commit them.

Unlike sed, you can double check before you fat finger your edit.

Preview (with fzf)

Selectively replace std -> joseph joestar in the sad repo.

You can pick and choose which changes to apply.

You can also choose the clustering factor for changes using --unified=<n>. (Same as in GNU diff)


Preview (no fzf)

Replace all'"(\d+)"' -> '🌈$1🌈' in the chromium repo.

use --commit or -k to commit changes all at once.

-c is taken because sad has to trick fzf into thinking it's bash :)


How to use sad?

with fzf

export GIT_PAGER='<highlighter-of-your-choice>'
# ^ can be done in your bash/zsh/rc file.
find "$FIND_ARGS" | sad '<pattern>' '<replacement>'

without fzf

find "$FIND_ARGS" | sad '<pattern>' '<replacement>' | highlighter-of-your-choice


find "$FIND_ARGS" | sad '<pattern>' '<replacement>' --pager=<highlighter-of-your-choice>


export GIT_PAGER='<highlighter-of-your-choice>'
find "$FIND_ARGS" | sad '<pattern>' '<replacement>'

gotta go fast

If you wanna go fast.

  • preview to verify you really want the changes.

  • run with --commit, and redirect stdout to a file or /dev/null


Technically none of these are "required", but they make sad so much happier.

If you install the things below, sad will automatically use them. It's progressive enhancement!

Commandline fuzzer


sad does not come with a UI, it uses fzf to perform selection.

Diff Colorizer

Any git compatible colourizer would work. I perfer these two:


fd <files> | sad <pattern> <replacement> | delta


fd <files> | sad <pattern> <replacement> | diff-so-fancy | less

Environmental Variables

Name Function
GIT_PAGER sad will use the same pager as git


Name Function
-f --flags Regex flags, see below
-k --commit No preview, write changes to file
-0 --read0 Use \x00 as stdin delimiter
-e --exact String literal mode
-p --pager Colourizing program, disable = never
--fzf Additional Fzf options, disable = never
-u --unified Same as in GNU diff, affects hunk size

Regex Flags

By default, sad uses smartcase, and multiline matching.

Name Function
i case insensitive (works for --exact mode as well)
I case sensitive (works for --exact mode as well)
m multiline: ^ $ match each line
M singleline: ^ $ match entire document
s allow . match \n
x ignore whitespace and allow # comments

Exit Codes

Code Meaning
0 Good
1 Bad
130 Interrupted (ie. user cancel), or if using fzf, it will always exit 130.



brew install ms-jpq/sad/sad

Snap Store:

coming soon...

Distribution packages:


You can download sad deb packages from the github release page.

Arch Linux:

You can find the PKGBUILD on the AUR.


Missing a package for your favourite distribution? Let us know!

Compile from source:


To compile sad yourself you'll have to make sure you have
Rust and cargo installed.

Install instructions:

To install cargo from source you can run the following commands:

cargo install --locked --all-features --path .

If you want to install it in a specific directory you can provide the --root
flag, like so:

cargo install --locked --all-features --root="/usr/bin/" --path .

What about stdin -> stdout

If you just want to edit the shell stream, I would recommand sd, it uses the same concept, but its more for in stream edits. sad was inspired by my initial useage of sd.

command1 | sd '<pattern>' '<replacement>' | command2

ripgrep with --replace also works

command1 | rg --passthru --replace '<replacement>' -- '<pattern>' | command2

Take note however, rg will exit 1, it it finds no matches.