Skip to content
Latchkey

sed Address Negation with the ! Operator

Putting ! after a sed address runs the command on every line that does not match.

Sometimes it is easier to say which lines to skip. The ! operator flips any address so the command applies to the complement.

What it does

A ! immediately after an address negates it. The command then runs on all lines except those the address would have matched. It works with numbers, regexes, ranges, and the $ last-line address.

Common usage

Terminal
sed '1!d' file                  # keep only line 1 (delete all others)
sed '/^#/!s/ /_/g' file         # squeeze spaces except on comment lines
sed -n '/error/!p' app.log      # print lines that do NOT match error
sed '$!N' file                  # join pairs, leaving last line alone

Options

FormWhat it does
N!cmdRun cmd on every line except line N
/regex/!cmdRun cmd on lines not matching the regex
M,N!cmdRun cmd outside the range M to N
$!cmdRun cmd on every line except the last
addr !dDelete everything except the addressed lines

In CI

Negation is portable between GNU and BSD sed. A handy idiom is /pattern/!d to keep only matching lines, which behaves like grep but stays inside a single sed program when you are already running other commands.

Common errors in CI

Spacing matters: most builds accept both 1!d and 1 !d, but a stray ! with no address, such as a leading !d, raises sed: -e expression #1, char N: missing command or an unexpected `!' error. Keep the ! directly after the address.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →