Anatomy of the s Command
The substitute command has the form s/regexp/replacement/flags. sed searches the pattern space for text matching the regexp and replaces it with the replacement string. Without any flags, s replaces only the first match on each line. The regexp is a regular expression (basic regular expressions by default), while the replacement is mostly literal text apart from a few special characters. This single command handles the overwhelming majority of real-world sed usage.
Cricket analogy: The s command is like a targeted field change: you name the exact area (the regexp), specify who moves there (the replacement), and by default only the first fielder in that zone is repositioned.
# Replace only the first 'apple' on each line
sed 's/apple/orange/' fruit.txt
# Replace every 'apple' on each line with the g flag
sed 's/apple/orange/g' fruit.txtFlags: g, i, p, and Numbers
Flags after the final delimiter change how substitution behaves. The g flag makes the replacement global, affecting every match on the line rather than just the first. A number N replaces only the Nth match, and combining Ng replaces the Nth and all after it. The i (or I) flag makes matching case-insensitive, and the p flag prints the line if a substitution occurred — most useful together with -n to emit only changed lines. These flags combine, so s/x/y/2gi is perfectly valid.
Cricket analogy: The g flag is like instructing every fielder in a zone to shift, not just one; the number N is like telling only the second slip to move, and Ng means that slip and everyone behind them.
# Replace from the 2nd match onward
sed 's/,/;/2g' data.csv
# Case-insensitive replace
sed 's/error/ERROR/gi' app.log
# Print only lines where a substitution happened
sed -n 's/deprecated/REMOVED/p' api.txtChoosing a Different Delimiter
The slash in s/// is just the default delimiter; you may use almost any character instead. This is invaluable when the pattern or replacement contains slashes, such as file paths. Writing s#/usr/local#/opt# avoids a thicket of escaped backslashes and reads far more clearly. The character immediately after the s becomes the delimiter for that command, and it must then separate all three fields.
Cricket analogy: Swapping the delimiter is like changing your bowling angle to go around the wicket when the natural line is blocked — same delivery, a cleaner path to the target.
# Painful with slashes:
sed 's/\/usr\/local/\/opt/' paths.txt
# Clear with a different delimiter:
sed 's#/usr/local#/opt#' paths.txtThe Ampersand and Backreferences
In the replacement, an unescaped ampersand (&) stands for the entire matched text, letting you wrap or extend a match without retyping it. For finer control, parentheses in the regexp capture groups that you refer to as \1, \2, and so on in the replacement. In basic regular expressions the groups are written \( and \), while extended regexps (enabled with -E or -r) use plain parentheses. Backreferences make sed capable of surprisingly powerful reformatting, such as swapping two fields.
Cricket analogy: The ampersand is like the commentator repeating a batsman's full name before adding a title — you reuse the whole matched phrase, then decorate it, without spelling it out again.
# Wrap every matched number in brackets using &
sed 's/[0-9]\+/[&]/g' log.txt
# Swap 'First Last' into 'Last, First' with capture groups (BRE)
sed 's/\([A-Za-z]*\) \([A-Za-z]*\)/\2, \1/' names.txt
# Same with extended regex (cleaner)
sed -E 's/([A-Za-z]*) ([A-Za-z]*)/\2, \1/' names.txtRemember the g flag: s/x/y/ changes only the FIRST match per line. Forgetting g is the single most common sed mistake, leaving later matches on the same line untouched and producing baffling partial results.
- The s command has the form s/regexp/replacement/flags.
- Without g, only the first match on each line is replaced.
- Flags include g (global), N (Nth match), i (case-insensitive), and p (print on change).
- Any character can serve as the delimiter, which helps when matching paths.
- & in the replacement inserts the entire matched text.
- Capture groups (\1, \2) enable reordering and reformatting; use -E for cleaner syntax.
Practice what you learned
1. Without any flags, how many matches per line does s replace?
2. What does the & symbol mean in a sed replacement?
3. Which command replaces every comma on a line with a semicolon?
4. Why might you write s#/a/b#/c/d# instead of using slashes?
5. In basic regular expressions, how do you write a capture group?
Was this page helpful?
You May Also Like
What Is sed?
An introduction to sed, the non-interactive stream editor that transforms text line by line as it flows through a pipeline.
Running sed Scripts
How to invoke sed from the command line and from script files, including the key options that control input, output, and multi-command execution.
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.
Your First sed One-Liner
Build a genuinely useful sed one-liner from scratch, combining an address, a substitution, and options into a single practical command.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics