sed — stream editor reference
sed is a non-interactive stream editor: it reads input line by line into a buffer called the pattern space, applies a script of editing commands, and writes the result out. It excels at find-and-replace, deleting or printing selected lines, and multi-line transforms via the hold space. This page is a searchable, offline reference to sed’s addresses, commands, substitute flags and command-line options, each with a working example.
How it works
Every sed command may be prefixed with an address that selects which lines it applies to:
- Addresses can be a line number
3, the last line$, a regex/re/, a range2,5or/a/,/b/, GNU step form1~2, or a negated formaddr!. - The substitute command
s/regex/replacement/flagsis the workhorse. Flags includeg(all matches), a numberN(the N-th match),p(print on change),i(case-insensitive) andm(multi-line). In the replacement,&is the whole match and\1..\9are captured groups. - Editing commands add (
a), insert (i), change (c), delete (d), print (p), transliterate (y) and quit (q). - Advanced commands move text between the pattern and hold spaces (
h,H,g,G,x) and branch with labels (:label,b,t,T) for loops.
The output model matters: with no -n, sed prints the pattern space at the end
of each cycle; with -n it prints nothing unless you ask.
Practical examples
Delete blank lines and comment lines:
sed '/^$/d; /^#/d' config
Replace every tab with a comma across the whole file, in place with a backup:
sed -i.bak 's/\t/,/g' data.tsv
Print only lines 10 through 20:
sed -n '10,20p' file
Join all lines into one using the hold-space loop idiom:
sed ':a; N; $!ba; s/\n/ /g' file
Extract lines between two patterns (inclusive):
sed -n '/START/,/END/p' file
Add a line after every line matching a pattern:
sed '/pattern/a\new line to insert' file
BSD versus GNU sed: the key differences
macOS ships BSD sed, while Linux typically has GNU sed. The most common points of divergence:
| Feature | GNU sed | BSD sed (macOS) |
|---|---|---|
| In-place edit | sed -i 's/x/y/' file | sed -i '' 's/x/y/' file |
| Extended regex | -E or -r | -E only |
| Step address | 1~2 (every other line) | not supported |
Multiline mode m flag | supported | not supported |
\w in regex | supported | not supported |
If a sed one-liner works on Linux but fails on macOS, check for GNU-only features
and use gsed (install via Homebrew) on macOS to get GNU behaviour.
Common mistakes to avoid
- Testing without
-i: always run the command without-ifirst to verify the output, then add-ionce confirmed. A wrong regex with-ioverwrites the original file immediately. - Forgetting
gflag:s/old/new/only replaces the first occurrence per line. Addgfor all occurrences. - Delimiter clashes: if your pattern contains
/, either escape it as\/or choose a different delimiter —s|/old/|/new/|guses|instead and is much easier to read. - Hold-space confusion:
hcopies pattern space to hold space (overwriting it);Happends.gcopies hold to pattern;Gappends. Mixing these up silently drops lines.