sed Line Addressing: Numbers, $, and Regex
A sed address before a command restricts that command to matching lines: a number, the $ symbol, or a regex.
Every sed command can carry an address. Master the three single-line forms and you control exactly where substitutions and deletes apply.
What it does
An address precedes a command and limits it to specific lines. A bare number N matches line N, $ matches the last line, and /regex/ matches any line the regex hits. With no address, the command runs on every line.
Common usage
sed '1s/^/# /' file # prefix only line 1
sed '$s/$/ EOF/' file # append to the last line
sed '/^server:/s/dev/prod/' app.yml # change only under server:
sed -n '/BEGIN/=' file # print line numbers of matchesOptions
| Address | What it matches |
|---|---|
| N | Exactly line number N |
| $ | The last line of the input |
| /regex/ | Every line matching the regular expression |
| 0,/regex/ (GNU) | From the start until the first regex match |
| N~M (GNU) | Every Mth line starting at line N (step) |
| addr! | Invert: run the command on non-matching lines |
In CI
Number and $ addressing are POSIX and portable. The step form N~M and the 0,/regex/ start address are GNU extensions, so they fail on BSD sed; avoid them in macOS matrix jobs.
Common errors in CI
sed: -e expression #1, char N: unexpected `,' usually means a bad range address. On BSD sed, a GNU-only address such as 1~2p raises sed: 1: "1~2p": invalid command code ~. Use a regex or explicit range that both implementations accept.