100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Addresses and Line Selection

How to target specific lines in sed using line numbers, regex patterns, ranges, and the negation operator so commands run only where you want.

FoundationsIntermediate10 min readJul 10, 2026
Analogies

Why Addresses Matter

By default every sed command runs on every line. An address is a prefix that restricts a command to only the lines you specify, giving you surgical control. Addresses come before the command: for example, '3d' deletes line 3, and '/error/d' deletes every line containing 'error'. Almost any command accepts an address, and mastering them is what elevates sed from simple substitution to precise line editing.

🏏

Cricket analogy: An address is like a captain setting an attacking field only for a specific batsman — the tactic applies to the chosen target, not to every player at the crease.

Line Numbers and the Last Line

The simplest address is a line number, counted from 1 across the whole input. So '1d' removes the first line — handy for stripping a CSV header — and '5s/old/new/' substitutes only on line 5. The special address $ matches the very last line of input, regardless of how many lines there are. You can also select every Nth line with the GNU extension first~step, so '0~3' matches lines 3, 6, 9, and so on.

🏏

Cricket analogy: Line number 1 is like removing the nightwatchman from the top of the order; $ is the last man in, the number 11 tailender who always comes last no matter the innings length.

bash
# Delete the header line of a CSV
sed '1d' data.csv

# Substitute only on the last line
sed '$s/$/  <-- end/' file.txt

# GNU: uppercase-tag every third line
sed '0~3s/^/[3n] /' list.txt

Regex Addresses and Ranges

A regular expression enclosed in slashes selects every line the pattern matches, so '/^#/d' deletes all comment lines beginning with #. You can also form a range with two addresses separated by a comma: addr1,addr2 selects from the first line matching addr1 through the next line matching addr2, inclusive. Ranges mix types freely — '/BEGIN/,/END/d' deletes a block between markers, and '1,/^$/d' deletes from the top down to the first blank line.

🏏

Cricket analogy: A regex address is like targeting every left-handed batsman; a range like /BEGIN/,/END/ is a bowling spell from the fall of one wicket to the next, covering everything in between.

bash
# Delete all comment lines
sed '/^#/d' config.conf

# Delete a block between markers (inclusive)
sed '/-- BEGIN --/,/-- END --/d' report.txt

# Print only lines 10 to 20 (suppress the rest)
sed -n '10,20p' access.log

The idiom 'sed -n '10,20p' file' mirrors head/tail: -n suppresses default output and the range with p prints just that window of lines. It is a quick way to extract a slice of a large file.

Negating an Address With !

Appending an exclamation mark to an address inverts it, so the command runs on every line that does NOT match. For instance '/error/!d' deletes all lines that do not contain 'error', which is effectively a grep for 'error'. Negation composes with any address type, letting you say 'apply this everywhere except here' — often clearer than constructing a positive pattern for the complement.

🏏

Cricket analogy: Negation is like a field set for everyone except the star batsman — the plan applies to all opponents but the one you deliberately exclude.

bash
# Keep only lines containing 'error' (delete the rest)
sed '/error/!d' app.log

# Add a prefix to every line EXCEPT blank ones
sed '/^$/!s/^/> /' quote.txt

A range addr1,addr2 always includes at least one line and, if addr2 never matches again, extends to the end of the input. Also, once a range closes, sed can reopen it later if addr1 matches again — ranges are not one-shot by default.

  • An address prefixes a command to restrict it to chosen lines.
  • Line numbers count from 1, and $ matches the last line of input.
  • A /regex/ address selects every line the pattern matches.
  • addr1,addr2 forms an inclusive range across lines or patterns.
  • 'sed -n 'A,Bp'' extracts a slice of lines like head/tail combined.
  • Appending ! negates an address so the command runs on non-matching lines.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#SedStreamEditorStudyNotes#AddressesAndLineSelection#Addresses#Line#Selection#Matter#StudyNotes#SkillVeris#ExamPrep