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

Advanced sed Scripting

Move past basic search-and-replace to use sed's address ranges, hold space, branching, and in-place editing for multi-line, stateful text transformations.

I/O & Text ProcessingAdvanced10 min readJul 10, 2026
Analogies

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.

bash
# 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.yaml

Hold 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,10 or /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) with b (unconditional branch) and t (branch-if-substituted) enable loop-like control flow in sed.
  • t label branches only if a substitution has succeeded since the last line was read or the last branch, useful for repeat-until-stable transforms.
  • sed -i edits 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

Was this page helpful?

Topics covered

#Bash#AdvancedBashScriptingStudyNotes#DevOps#AdvancedSedScripting#Advanced#Sed#Scripting#Addresses#StudyNotes#SkillVeris