Stream editing reference
sed Cheat Sheet
A practical sed reference for searching, substituting, deleting, printing, editing files, composing scripts, and writing portable commands across GNU, BSD, macOS, and POSIX sed.
1. Mental model
What sed does
sed reads input as a stream, loads one line at a time into the pattern space, applies editing commands, then prints the pattern space by default.
When sed is a good fit
Use sed for line-oriented substitutions, filtering, small rewrites, and simple scripted transforms in shell pipelines.
When to switch tools
Use awk for column-aware logic and arithmetic, perl/ruby/python for nested parsing, and structured tools for JSON, XML, YAML, and HTML.
2. Quick start
| Task | Command | Notes |
|---|---|---|
| Replace first match per line | sed 's/foo/bar/' file | Only the first match on each line. |
| Replace all matches per line | sed 's/foo/bar/g' file | g means global within the line. |
| Print matching lines | sed -n '/error/p' app.log | -n disables automatic printing. |
| Delete matching lines | sed '/debug/d' app.log | Deletes from output, not the input file. |
| Print line range | sed -n '10,20p' file | Inclusive range. |
| Run multiple commands | sed -e 's/foo/bar/g' -e '/tmp/d' file | Commands run in order. |
| Use extended regex | sed -E 's/[0-9]+/N/g' file | Portable on modern GNU, BSD, and macOS sed. |
| Preview an in-place edit | sed 's/old/new/g' file > file.new | Safer than editing in place first. |
Most common shape
sed 'address command' file
sed 's/pattern/replacement/flags' file
sed -n '/pattern/p' file
Pipeline shape
printf '%s\n' alpha beta gamma | sed 's/a/A/g'
git diff --name-only | sed -n '/\.go$/p'
3. Invocation and options
| Option | Use | Example |
|---|---|---|
-n | Suppress automatic printing. | sed -n '/TODO/p' file |
-e script | Add a command. | sed -e 's/a/b/' -e 's/c/d/' file |
-f file | Read commands from a script file. | sed -f rewrite.sed input.txt |
-E | Use extended regular expressions. | sed -E 's/(cat|dog)/pet/g' file |
-i | Edit files in place. | sed -i.bak 's/old/new/g' file |
-l | Line-buffer output on GNU sed. | tail -f log | sed -l 's/error/ERROR/' |
--version | Show GNU sed version. | sed --version |
Using shell variables safely
name='alice'
sed "s/user/$name/g" file
If the variable can contain /, &, or backslashes, escape it first or use a different tool. sed has no built-in shell-variable quoting.
4. Addresses and ranges
An address selects where a command applies. Without an address, the command applies to every input line.
| Address | Meaning | Example |
|---|---|---|
5 | Line 5. | sed -n '5p' file |
$ | Last line. | sed -n '$p' file |
/re/ | Lines matching a regex. | sed -n '/error/p' file |
\#re# | Regex with alternate delimiter. | sed -n '\#/usr/local#p' file |
3,8 | Lines 3 through 8. | sed -n '3,8p' file |
/start/,/end/ | From first start match through next end match. | sed -n '/BEGIN/,/END/p' file |
1,/end/ | From first line through first end match. | sed '1,/done/d' file |
addr! | Invert the address. | sed -n '/keep/!p' file |
Addressed commands
sed '5d' file
sed '10,20s/foo/bar/g' file
sed '/BEGIN/,/END/s/old/new/g' file
sed '/skip/!s/[[:space:]]\+$//' file
5. Substitution
The s command is sed's everyday workhorse.
sed 's/pattern/replacement/' file
sed 's/pattern/replacement/g' file
sed 's#pattern#replacement#g' file
| Flag or token | Meaning | Example |
|---|---|---|
g | Replace all matches on a line. | sed 's/foo/bar/g' file |
1, 2, 3 | Replace only the numbered match on each line. | sed 's/:/,/2' file |
p | Print lines where substitution happened. | sed -n 's/error/ERROR/p' file |
w file | Write changed lines to a file. | sed -n 's/TODO/DONE/w changed.txt' file |
& | Entire matched text in replacement. | sed 's/[0-9][0-9]*/[&]/g' file |
\1 through \9 | Captured groups in replacement. | sed -E 's/(.*), (.*)/\2 \1/' names |
\/ | Literal slash when slash is delimiter. | sed 's/\/tmp/\/var\/tmp/g' file |
\& | Literal ampersand in replacement. | sed 's/and/\&/g' file |
Use a better delimiter for paths and URLs
sed 's#/usr/local#/opt/homebrew#g' file
sed 's|https://old.example|https://new.example|g' file
Capture and rearrange
sed -E 's/^([^:]+):([^:]+)$/user=\1 id=\2/' users.txt
sed -E 's/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/\2\/\3\/\1/' dates.txt
6. Regular expressions
Basic regular expressions
Default sed uses basic regular expressions. Grouping, alternation, and one-or-more need backslashes.
sed 's/\(cat\|dog\)/pet/g' file
sed 's/[0-9]\{1,\}/N/g' file
Extended regular expressions
-E makes regexes easier to read and is the best default for non-trivial sed commands.
sed -E 's/(cat|dog)/pet/g' file
sed -E 's/[0-9]+/N/g' file
| Pattern | Meaning | Example |
|---|---|---|
. | Any character except newline. | sed 's/./x/g' |
* | Zero or more of previous atom. | sed 's/ */ /g' |
^ | Start of pattern space. | sed 's/^/> /' |
$ | End of pattern space. | sed 's/$/;/' |
[abc] | One character from set. | sed 's/[aeiou]/*/g' |
[^abc] | One character not in set. | sed 's/[^0-9]/ /g' |
[[:digit:]] | POSIX digit class. | sed 's/[[:digit:]]/#/g' |
[[:space:]] | POSIX whitespace class. | sed 's/[[:space:]][[:space:]]*/ /g' |
\(...\) | BRE capture group. | sed 's/^\(.*\):\(.*\)$/\2:\1/' |
(...) | ERE capture group with -E. | sed -E 's/^(.*):(.*)$/\2:\1/' |
N.
7. Printing, deleting, and filtering
| Command | Meaning | Example |
|---|---|---|
p | Print pattern space. | sed -n '/error/p' log |
d | Delete pattern space and start next cycle. | sed '/debug/d' log |
q | Quit after current cycle. | sed '10q' file |
= | Print current line number. | sed -n '/error/=' log |
l | Print visibly escaped pattern space. | sed -n 'l' file |
n | Print current line unless -n, read next line. | sed 'n;d' file |
Common filters
sed -n '1,20p' file
sed -n '/BEGIN/,/END/p' file
sed '/^[[:space:]]*$/d' file
sed '/^[[:space:]]*#/d' file
sed -n '$p' file
sed '10q' file
8. Insert, append, change, transform
| Command | Meaning | Example |
|---|---|---|
i\ | Insert text before selected line. | sed '1i\Header' file |
a\ | Append text after selected line. | sed '$a\Footer' file |
c\ | Replace selected line or range. | sed '/old/c\replacement' file |
y/src/dst/ | Transliterate characters. | sed 'y/abc/ABC/' file |
r file | Read file after selected line. | sed '/marker/r snippet.txt' file |
w file | Write selected pattern space to file. | sed -n '/error/w errors.log' app.log |
Portable multi-line form
sed '1i\
Header line
' file
sed '/marker/a\
Inserted after marker
' file
i\text, a\text, and c\text forms are accepted by many sed implementations, but the newline form is the safer POSIX style.
9. File editing and backups
Preview first
sed 's/old/new/g' file
sed 's/old/new/g' file > file.new
diff -u file file.new
GNU and BSD backup edit
sed -i.bak 's/old/new/g' file
Creates file.bak and writes changes to file.
macOS no-backup edit
sed -i '' 's/old/new/g' file
BSD/macOS sed requires a separate empty backup suffix argument.
GNU no-backup edit
sed -i 's/old/new/g' file
This form fails on macOS/BSD sed because -i expects a suffix argument there.
| Goal | Command | Notes |
|---|---|---|
| Edit many files with backups | sed -i.bak 's/foo/bar/g' *.txt | Portable between GNU and BSD for basic cases. |
| Remove backup files after inspection | find . -name '*.bak' -type f -delete | Check before deleting in real projects. |
| Preserve original while transforming | sed 's/foo/bar/g' old.txt > new.txt | Best for scripts where failure should not mutate input. |
10. Pattern space and multi-line commands
The pattern space is sed's current working buffer. Most commands operate on it, then sed prints it and starts the next cycle.
| Command | Meaning | Use |
|---|---|---|
N | Append next input line to pattern space with a newline. | Work across adjacent lines. |
D | Delete up to first newline and restart cycle. | Sliding multi-line windows. |
P | Print up to first newline. | Print first line from multi-line pattern space. |
n | Read next line into pattern space. | Skip or pair lines. |
Join lines ending with a backslash
sed ':a
/\\$/{
N
s/\\\n//
ba
}' file
Replace a newline between two loaded lines
sed 'N;s/foo\nbar/foo bar/' file
11. Hold space
The hold space is a second buffer. It lets sed remember text between cycles.
| Command | Meaning | Effect |
|---|---|---|
h | Copy pattern space to hold space. | Overwrite memory. |
H | Append pattern space to hold space. | Keep accumulating. |
g | Copy hold space to pattern space. | Restore memory. |
G | Append hold space to pattern space. | Add memory after current line. |
x | Exchange hold and pattern spaces. | Swap current and remembered text. |
Print file in reverse
sed -n '1!G;h;$p' file
Append the first line after every later line
sed '1h;1d;G' file
12. Branching and labels
| Command | Meaning | Example |
|---|---|---|
:label | Define a label. | :again |
b label | Branch unconditionally. | bagain |
t label | Branch if a substitution succeeded since last input or branch. | tdone |
T label | GNU sed branch if no substitution succeeded. | Tmissing |
Collapse repeated spaces
sed ':again
s/ / /
tagain' file
Remove nested pairs one level at a time
sed ':again
s/([^()]*)//
tagain' file
13. sed script files
For more than one or two commands, put sed code in a file and run it with -f.
cleanup.sed
s/[[:space:]]\+$//
/^[[:space:]]*$/d
s/[[:space:]][[:space:]]*/ /g
Run it
sed -f cleanup.sed input.txt
sed -f cleanup.sed input.txt > output.txt
Grouped commands
sed '/BEGIN/,/END/{
s/foo/bar/g
/^[[:space:]]*$/d
}' file
14. Recipes
| Task | Command | Notes |
|---|---|---|
| Trim trailing whitespace | sed 's/[[:space:]]\+$//' file | Use before comparing generated text. |
| Trim leading whitespace | sed 's/^[[:space:]]*//' file | Removes indentation. |
| Collapse whitespace runs | sed 's/[[:space:]][[:space:]]*/ /g' file | Line-oriented only. |
| Remove blank lines | sed '/^[[:space:]]*$/d' file | Works with spaces and tabs. |
| Remove comments and blank lines | sed '/^[[:space:]]*#/d;/^[[:space:]]*$/d' file | Good for simple config files. |
| Number matching lines | sed -n '/error/{=;p;}' log | Line number prints on its own line. |
| Print between markers | sed -n '/START/,/END/p' file | Includes marker lines. |
| Delete between markers | sed '/START/,/END/d' file | Deletes marker lines too. |
| Replace only in range | sed '/START/,/END/s/foo/bar/g' file | Leaves the rest unchanged. |
| Print every other line | sed -n '1~2p' file | GNU sed. Use sed -n 'p;n' for a portable first-line pattern. |
| Prefix each line | sed 's/^/[prefix] /' file | Uses start anchor. |
| Suffix each line | sed 's/$/;/' file | Uses end anchor. |
| CSV swap two fields | sed -E 's/^([^,]*),([^,]*)/\2,\1/' file | Only safe for simple CSV without quotes. |
| Extract value after key | sed -n 's/^version=[[:space:]]*//p' file | Prints only changed lines. |
| Mask numbers | sed -E 's/[0-9]+/[redacted]/g' file | Requires -E for +. |
| Normalize CRLF to LF | sed 's/\r$//' file | Shell and sed must pass carriage return as intended. |
| Show tabs and ends | sed -n 'l' file | Useful when whitespace is confusing. |
| Insert header | sed '1i\Header' file | Use portable newline form in scripts. |
| Append footer | sed '$a\Footer' file | Use portable newline form in scripts. |
| Keep first 100 lines | sed '100q' file | Similar to head -n 100. |
15. Portability and troubleshooting
Prefer these for portability
sed -E 's/(old|legacy)/new/g' file
sed -i.bak 's/old/new/g' file
sed -n '/pattern/p' file
sed -f script.sed file
Check your sed
sed --version
which sed
command -v gsed
On macOS, Homebrew GNU sed is usually installed as gsed.
| Issue | Likely cause | Fix |
|---|---|---|
sed: 1: ... invalid command code | BSD/macOS sed parsed an option or escaped command differently. | Check -i syntax, command quoting, and newline forms for a, i, c. |
| Replacement contains the matched text unexpectedly | Unescaped & in replacement. | Use \& for a literal ampersand. |
| Path replacement is unreadable | Slash delimiter fights path slashes. | Use #, |, or another delimiter. |
+, ?, or | does not work | Default basic regex mode. | Use -E, or escape BRE operators where applicable. |
| Command works on Linux but not macOS | GNU sed extension. | Install and call gsed, or rewrite using POSIX/BSD syntax. |
| Command prints each line twice | Automatic print plus explicit p. | Add -n when using p as a filter. |
| Regex does not match across lines | sed reads one line per cycle. | Use N for small adjacent-line cases, or switch tools. |
| In-place edit damaged a file | Command was not previewed or backup was omitted. | Use -i.bak, review diffs, and keep changes under version control. |
GNU-only features to recognize
| Feature | GNU example | Portable alternative |
|---|---|---|
| Address step | sed -n '1~2p' file | sed -n 'p;n' file for odd lines. |
| Address offset | sed -n '/start/,+5p' file | Use awk, or a small sed script with counters. |
| Case conversion escapes | sed 's/.*/\U&/' file | Use awk, perl, tr, or GNU sed explicitly. |
\s, \w | sed -E 's/\s+/ /g' | Use POSIX classes such as [[:space:]]. |
T branch | sed 's/x/y/;T fail' | Use GNU sed or redesign the script. |