Replace Text
The substitute command is most of what sed gets used for. replaces the first occurrence on each line; makes it every occurrence.
| Command | What 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.
| Command | What 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.
| Command | What 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
| Command | What 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 ) |
Print Lines (-n and p)
turns off the default print-every-line behaviour, so prints only what you select.
| Command | What 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.
| Command | What 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
' fileRegex 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).
| Command | What 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
| Command | What 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' fileFor simple newline jobs, or is easier to read.
Variables and Special Characters
| Command | What 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.