Addresses and Ranges
sed applies each command to every line by default, but you can restrict a command to specific lines using addresses: a single line number, a regex like /pattern/, a range 5,10, a range between two regexes /START/,/END/, or a step address 1~2 (every second line starting at line 1). Combining ! with an address negates it, so 5,10!d deletes every line except lines 5 through 10, which is a common trick for extracting only a specific block from a larger file.
Cricket analogy: Only reviewing overs 10 through 20 of a match highlights reel instead of the full innings mirrors sed applying a command only to the line range 10,20.
# Print only the block between markers (inclusive)
sed -n '/^BEGIN_CONFIG/,/^END_CONFIG/p' app.conf
# Delete every line EXCEPT lines 5 through 10
sed '5,10!d' file.txt
# Every second line starting at line 1 (GNU sed step address)
sed -n '1~2p' file.txt
# In-place edit with a backup extension, only within a line range
sed -i.bak '10,20 s/foo/bar/g' config.yamlHold Space and Multi-Line Patterns
Beyond the pattern space (the current line being processed), sed maintains a second buffer called the hold space, manipulated with h/H (copy/append pattern space to hold space) and g/G (copy/append hold space back to pattern space), plus x to swap the two entirely. This is what makes stateful, multi-line transformations possible, such as reversing the order of lines in a file (tac-like behavior) or joining every pair of lines, tasks that a simple single-line s/// substitution cannot express because it only ever sees one line at a time.
Cricket analogy: A twelfth man holding a spare bat on the boundary that can be swapped in for a damaged one mid-over mirrors sed's hold space acting as a secondary buffer swapped with the pattern space via x.
A classic idiom to reverse the lines of a file using only sed (no tac) is: sed -n '1!G;h;$p' file.txt. It appends each new line to the hold space above what's already there (1!G), stores the growing result back in the hold space (h), and prints it only at the end ($p).
Branching and In-Place Editing
sed supports control flow through labels (:label) and branch commands: b label branches unconditionally, and t label branches only if a substitution has succeeded since the last input line was read or the last branch was taken, which enables loops such as repeatedly collapsing multiple spaces until none remain. For applying changes directly to files rather than printing to stdout, sed -i edits in place; GNU sed accepts -i.bak to keep a backup with a .bak suffix, while BSD/macOS sed requires an explicit (possibly empty) suffix argument like -i '', a portability gotcha that trips up many cross-platform scripts.
Cricket analogy: A captain who keeps bringing back the same bowler for another over as long as wickets keep falling, but switches bowlers the moment the wicket-taking stops, mirrors sed's t label branching only while substitutions keep succeeding.
sed -i syntax is NOT portable between GNU sed (Linux) and BSD sed (macOS): GNU sed accepts -i.bak (suffix immediately attached) or bare -i, while BSD sed requires a separate argument even if empty, -i ''. A script using sed -i 's/a/b/' file will silently behave differently or error out depending on the platform, so cross-platform scripts should detect the sed variant or use a portable workaround like writing to a temp file.
- sed addresses can be line numbers, regexes, ranges (
5,10or/START/,/END/), step addresses (1~2), and can be negated with!. - The hold space is a secondary buffer manipulated with h/H, g/G, and x, enabling multi-line and stateful transformations.
sed -n '1!G;h;$p'is a classic hold-space idiom to reverse a file's line order.- Labels (
:label) withb(unconditional branch) andt(branch-if-substituted) enable loop-like control flow in sed. t labelbranches only if a substitution has succeeded since the last line was read or the last branch, useful for repeat-until-stable transforms.sed -iedits files in place, but its exact syntax differs between GNU sed and BSD/macOS sed.- Restricting commands to address ranges is the standard way to safely edit only part of a larger file.
Practice what you learned
1. What does the sed command `5,10!d` do?
2. What is the hold space in sed used for?
3. In sed, what does the `t` command do?
4. Why is `sed -i 's/foo/bar/' file.txt` considered a portability risk?
5. Which sed address syntax selects every line between a line matching /START/ and a line matching /END/, inclusive?
Was this page helpful?
You May Also Like
Advanced awk Scripting
Go beyond simple field printing to use awk's associative arrays, user-defined functions, BEGIN/END blocks, and multiple field separators for real text-processing programs.
Combining grep, awk, and sed
Learn how to chain grep, awk, and sed into efficient pipelines, choosing the right tool for filtering, transforming, and extracting text at each stage.
Here-Documents and Here-Strings
Learn how to feed multi-line literal text into commands using heredocs (<<) and here-strings (<<<), including quoting rules and indentation control.
Related Reading
Related Study Notes in DevOps
Browse all study notesNginx Study Notes
DevOps · 30 topics
DevOpsAnsible Study Notes
DevOps · 30 topics
DevOpsAdvanced Kubernetes Study Notes
Kubernetes · 30 topics
DevOpsApache Kafka Study Notes
Kafka · 30 topics
DevOpsDocker & Kubernetes Study Notes
YAML · 40 topics
DevOpsCI/CD Tools & Pipelines Study Notes
YAML · 37 topics