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.

POSIX aware GNU/BSD notes 15 sections

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.

Default cycle: read a line, run commands, print unless suppressed, repeat. Most sed surprises come from forgetting the automatic print or from mixing GNU-only syntax into macOS/BSD sed.

2. Quick start

TaskCommandNotes
Replace first match per linesed 's/foo/bar/' fileOnly the first match on each line.
Replace all matches per linesed 's/foo/bar/g' fileg means global within the line.
Print matching linessed -n '/error/p' app.log-n disables automatic printing.
Delete matching linessed '/debug/d' app.logDeletes from output, not the input file.
Print line rangesed -n '10,20p' fileInclusive range.
Run multiple commandssed -e 's/foo/bar/g' -e '/tmp/d' fileCommands run in order.
Use extended regexsed -E 's/[0-9]+/N/g' filePortable on modern GNU, BSD, and macOS sed.
Preview an in-place editsed 's/old/new/g' file > file.newSafer 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

OptionUseExample
-nSuppress automatic printing.sed -n '/TODO/p' file
-e scriptAdd a command.sed -e 's/a/b/' -e 's/c/d/' file
-f fileRead commands from a script file.sed -f rewrite.sed input.txt
-EUse extended regular expressions.sed -E 's/(cat|dog)/pet/g' file
-iEdit files in place.sed -i.bak 's/old/new/g' file
-lLine-buffer output on GNU sed.tail -f log | sed -l 's/error/ERROR/'
--versionShow GNU sed version.sed --version
Quoting: Put sed programs in single quotes in the shell. Use double quotes only when you intentionally need shell variables to expand before sed runs.

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.

AddressMeaningExample
5Line 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,8Lines 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
Range behavior: A range starts when the first address matches and stays active until the second address matches. If the end never appears, the range continues to the end of input.

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 tokenMeaningExample
gReplace all matches on a line.sed 's/foo/bar/g' file
1, 2, 3Replace only the numbered match on each line.sed 's/:/,/2' file
pPrint lines where substitution happened.sed -n 's/error/ERROR/p' file
w fileWrite 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 \9Captured 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
PatternMeaningExample
.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/'
Newlines: sed normally processes one line at a time, so regexes do not cross line boundaries unless you explicitly append lines into the pattern space with commands such as N.

8. Insert, append, change, transform

CommandMeaningExample
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 fileRead file after selected line.sed '/marker/r snippet.txt' file
w fileWrite 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
Portability: The one-line 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.

GoalCommandNotes
Edit many files with backupssed -i.bak 's/foo/bar/g' *.txtPortable between GNU and BSD for basic cases.
Remove backup files after inspectionfind . -name '*.bak' -type f -deleteCheck before deleting in real projects.
Preserve original while transformingsed 's/foo/bar/g' old.txt > new.txtBest 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.

CommandMeaningUse
NAppend next input line to pattern space with a newline.Work across adjacent lines.
DDelete up to first newline and restart cycle.Sliding multi-line windows.
PPrint up to first newline.Print first line from multi-line pattern space.
nRead 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.

CommandMeaningEffect
hCopy pattern space to hold space.Overwrite memory.
HAppend pattern space to hold space.Keep accumulating.
gCopy hold space to pattern space.Restore memory.
GAppend hold space to pattern space.Add memory after current line.
xExchange 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
Readability: Hold-space sed is powerful but quickly becomes dense. For scripts that other people must maintain, awk is often clearer.

12. Branching and labels

CommandMeaningExample
:labelDefine a label.:again
b labelBranch unconditionally.bagain
t labelBranch if a substitution succeeded since last input or branch.tdone
T labelGNU 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
Ordering matters: sed commands see the output of earlier commands in the same cycle. Put broad cleanup before commands that depend on cleaned text.

14. Recipes

TaskCommandNotes
Trim trailing whitespacesed 's/[[:space:]]\+$//' fileUse before comparing generated text.
Trim leading whitespacesed 's/^[[:space:]]*//' fileRemoves indentation.
Collapse whitespace runssed 's/[[:space:]][[:space:]]*/ /g' fileLine-oriented only.
Remove blank linessed '/^[[:space:]]*$/d' fileWorks with spaces and tabs.
Remove comments and blank linessed '/^[[:space:]]*#/d;/^[[:space:]]*$/d' fileGood for simple config files.
Number matching linessed -n '/error/{=;p;}' logLine number prints on its own line.
Print between markerssed -n '/START/,/END/p' fileIncludes marker lines.
Delete between markerssed '/START/,/END/d' fileDeletes marker lines too.
Replace only in rangesed '/START/,/END/s/foo/bar/g' fileLeaves the rest unchanged.
Print every other linesed -n '1~2p' fileGNU sed. Use sed -n 'p;n' for a portable first-line pattern.
Prefix each linesed 's/^/[prefix] /' fileUses start anchor.
Suffix each linesed 's/$/;/' fileUses end anchor.
CSV swap two fieldssed -E 's/^([^,]*),([^,]*)/\2,\1/' fileOnly safe for simple CSV without quotes.
Extract value after keysed -n 's/^version=[[:space:]]*//p' filePrints only changed lines.
Mask numberssed -E 's/[0-9]+/[redacted]/g' fileRequires -E for +.
Normalize CRLF to LFsed 's/\r$//' fileShell and sed must pass carriage return as intended.
Show tabs and endssed -n 'l' fileUseful when whitespace is confusing.
Insert headersed '1i\Header' fileUse portable newline form in scripts.
Append footersed '$a\Footer' fileUse portable newline form in scripts.
Keep first 100 linessed '100q' fileSimilar 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.

IssueLikely causeFix
sed: 1: ... invalid command codeBSD/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 unexpectedlyUnescaped & in replacement.Use \& for a literal ampersand.
Path replacement is unreadableSlash delimiter fights path slashes.Use #, |, or another delimiter.
+, ?, or | does not workDefault basic regex mode.Use -E, or escape BRE operators where applicable.
Command works on Linux but not macOSGNU sed extension.Install and call gsed, or rewrite using POSIX/BSD syntax.
Command prints each line twiceAutomatic print plus explicit p.Add -n when using p as a filter.
Regex does not match across linessed reads one line per cycle.Use N for small adjacent-line cases, or switch tools.
In-place edit damaged a fileCommand was not previewed or backup was omitted.Use -i.bak, review diffs, and keep changes under version control.

GNU-only features to recognize

FeatureGNU examplePortable alternative
Address stepsed -n '1~2p' filesed -n 'p;n' file for odd lines.
Address offsetsed -n '/start/,+5p' fileUse awk, or a small sed script with counters.
Case conversion escapessed 's/.*/\U&/' fileUse awk, perl, tr, or GNU sed explicitly.
\s, \wsed -E 's/\s+/ /g'Use POSIX classes such as [[:space:]].
T branchsed 's/x/y/;T fail'Use GNU sed or redesign the script.