Cheat Sheet

sed Examples

sed edits text as it streams through a pipe or over a file: replace, delete, insert, print. Every example here is paste-ready, and the macOS differences that break sed -i for Mac users get their own section.

Last updated September 5, 2026

Replace Text

The substitute command is most of what sed gets used for. replaces the first occurrence on each line; makes it every occurrence.

CommandWhat it does
Replace the first match on each line
Replace every match ( = global)
Replace only the 2nd match on each line
Case-insensitive match (GNU sed; BSD lacks )
Any delimiter works; use or when the text has slashes
is the whole match: error becomes [error]
Substitute only on lines matching a pattern
Substitute only on line 3
Strip trailing whitespace
Works on piped input too (GNU sed prints as newline)

Edit Files In Place

Without , sed prints the result and leaves the file alone. That is the safe way to test an expression first.

CommandWhat it does
Dry run: prints the result, file untouched
Edit the file in place (GNU sed / Linux)
In place, keeping the original as file.bak (works everywhere)
Edit every .conf in the directory
Edit every matching file in a tree (see the grep cheat sheet)
The find equivalent

sed on macOS

macOS ships BSD sed, and the biggest difference is : BSD requires a backup extension argument, GNU does not. on a Mac fails with "invalid command code" or "undefined label" because gets read as the backup extension.

CommandWhat it does
In-place edit on macOS (empty string = no backup)
Portable form: same command on macOS and Linux
Portable, without keeping the backup
Installs GNU sed as , which takes Linux syntax

Other BSD gaps to know: no case-insensitive flag, and / insert text needs a real newline after the backslash. for extended regex works on both.

Delete Lines

CommandWhat it does
Delete lines matching a pattern
Delete empty lines
Delete comments and empty lines
Delete the first line (drop a header)
Delete the last line
Delete lines 2 through 5
Delete from line 10 to the end
Delete from one pattern to another, inclusive
Delete everything except matching lines (same as )

turns off the default print-every-line behaviour, so prints only what you select.

CommandWhat it does
Print line 5 only
Print lines 2 through 4
Print the last line
Print matching lines (grep in sed clothing)
Print from one pattern to another
Print the first 10 lines, then quit (fast on huge files)
Every 3rd line starting at 1 (GNU only)
Print only the rewritten lines: extract a value

Insert and Append

inserts before a line, appends after it, replaces it entirely.

CommandWhat it does
Insert a line at the top (GNU syntax)
Append a line at the end
Add a line after each match
Add a line before each match
Replace the whole matching line
Append after a specific line number

BSD/macOS sed wants a backslash and a literal newline after , , and ; the one-line GNU forms above fail there. Use , or:

sed -i '' '1i\
header line
' file

Regex and Capture Groups

sed's default dialect is basic regex (BRE): groups and / need backslashes. switches to extended regex and works on both GNU and BSD sed ( is the older GNU spelling).

CommandWhat it does
BRE capture groups: "Doe, Jane" becomes "Jane Doe"
Same with -E: no backslashes on the parens
(one or more) needs -E
(optional) needs -E
Alternation needs -E
The BRE spelling of
First field of a colon-separated file
Collapse runs of whitespace

sed has no or in any dialect: use and . is greedy and there are no lazy quantifiers, so match "up to the next X" with .

Multiple Commands

CommandWhat it does
Run several expressions in order
Same, separated by semicolons
Group commands to run on matching lines ( steps to the next line)
Read commands from a script file, one per line

sed works line by line, so a plain never matches. The classic join-all-lines one-liner pulls the file into the buffer first (GNU sed):

sed ':a;N;$!ba;s/\n/ /g' file

For simple newline jobs, or is easier to read.

Variables and Special Characters

CommandWhat it does
Double quotes let the shell expand
Another delimiter when the variable holds slashes
Command substitution works too
A literal in the replacement must be escaped
A literal backslash is (doubled again by shell quoting)
To match a literal , escape it in the pattern
Escape to match them literally

Gotchas

  • needs on macOS and plain on Linux. is the only spelling that works on both unchanged.
  • No , no , no lazy in sed regex, in any version. Use , , and .
  • An unescaped in the replacement inserts the whole match. This bites when the replacement is a shell variable containing .
  • Prefer over for extended regex: GNU sed takes both, BSD sed only .
  • Single-quote sed expressions unless you need a variable expanded. Inside double quotes the shell eats backslashes and before sed sees them.
  • grep answers "which lines", sed rewrites them, awk works per column. See the grep cheat sheet and awk cheat sheet.

sed Cheat Sheet FAQ

How do I use a shell variable in sed?
Switch to double quotes so the shell expands it: sed "s/localhost/$HOST/g" config. Two things break this: a slash inside the variable ends the pattern early, so use another delimiter (sed "s|/var/www|$DOCROOT|g"), and an & or \ in the variable is interpreted by sed itself. For variables you control, that is fine; for arbitrary input, escape it first or reach for awk -v, which passes variables without re-parsing them.
Why does sed -i not work on macOS?
macOS ships BSD sed, where -i requires a backup extension as an argument. GNU sed accepts sed -i 's/a/b/' file, but on a Mac that reads s/a/b/ as the backup extension and fails with an 'undefined label' or 'invalid command code' error. Write sed -i '' 's/a/b/' file on macOS (empty string means no backup). The form that works on both is sed -i.bak 's/a/b/' file, deleting the .bak after. Or brew install gnu-sed and use gsed with the Linux syntax.
How do I replace a string that contains slashes?
Use a different delimiter; sed accepts almost any character after the s. sed 's|/var/www|/srv/http|g' and sed 's#http://#https://#g' both work with no escaping. The alternative is escaping every slash (s/\/var\/www\/... ), which is unreadable. Regex specials like . * [ ] still need a backslash regardless of delimiter, since only the delimiter changes.
How do I extract part of a line with sed?
Match the whole line, capture the part you want, and replace the line with the capture, printing only when it matched: sed -n 's/.*id=\([0-9]*\).*/\1/p' app.log prints just the digits after id=. With -E the parentheses lose their backslashes: sed -En 's/.*id=([0-9]+).*/\1/p'. When the target is a simple pattern rather than a position, grep -o is often shorter: grep -o 'id=[0-9]*' does most of the same job.
How do I replace text in multiple files at once?
Glob when the files are in one directory: sed -i 's/old/new/g' *.conf. Across a tree, let grep find the files and xargs feed them to sed: grep -rl 'old' src/ | xargs sed -i 's/old/new/g'. This touches only files that actually match, which keeps timestamps honest. On macOS add the empty backup argument: xargs sed -i '' 's/old/new/g'. Test the expression on one file before running it over hundreds.

Related cheat sheets