sed for Stream Editing
`sed` is a programmable stream editor. It is excellent for simple line-oriented transformations, but production use requires clear regex boundaries and caution around in-place editing and structured formats.
Learning objectives
By the end of this lesson
- Perform substitutions and deletions with sed.
- Use addresses and explicit printing.
- Apply capture groups and alternate delimiters.
- Update files with a portable temporary-file pattern.
- Recognize formats that should not be processed with sed.
1. sed is a line-oriented stream editor
flowchart LR I["input line"] --> P["pattern space"] P --> S["sed commands"] S --> O["output"] O --> I
By default, sed reads a line, applies its program, prints the pattern space, and repeats.
2. s/// performs substitution
printf '%s\n' 'environment=dev' |
sed 's/dev/staging/'Add the g flag when every matching occurrence on the line should be replaced.
printf '%s\n' 'dev dev dev' |
sed 's/dev/staging/g'3. Choose readable delimiters
printf '%s\n' '/srv/app/v1' |
sed 's#/srv/app/v1#/srv/app/v2#'The substitution delimiter does not have to be /. Pick a delimiter that minimizes escaping.
4. Addresses restrict commands to selected lines
sed '/^DEBUG/d' app.log
sed -n '1,5p' app.log-n suppresses default printing; the p command then explicitly emits selected lines.
5. Capture groups preserve parts of a record
printf '%s\n' 'version=2.14.7' |
sed -E 's/^version=([0-9]+)\..*/major=\1/'6. Shell variables and sed programs are different languages
old='dev'
new='staging'
sed "s/^environment=$old$/environment=$new/" app.envArbitrary variable text may contain regex or replacement metacharacters. Direct interpolation is safe only under a well-defined input contract.
7. Prefer explicit temporary-file updates for portability
tmp=$(mktemp)
if sed 's/^enabled=false$/enabled=true/' app.conf >"$tmp"; then
mv -- "$tmp" app.conf
else
status=$?
rm -f -- "$tmp"
exit "$status"
fiThis avoids implementation differences around sed -i and gives you a place to validate transformed content before replacement.
8. sed is not a structured-data parser
General JSON, YAML, and XML should be parsed with tools that understand their grammars, not line-oriented substitutions.
9. Hands-on lab: transform a simple env file
mkdir -p "$HOME/devops-academy/bash/chapter08/lesson03"
cd "$HOME/devops-academy/bash/chapter08/lesson03"
cat > app.env <<'EOF'
SERVICE=api
ENVIRONMENT=dev
REPLICAS=2
DEBUG=true
EOF
tmp=$(mktemp)
if sed -E \
-e 's/^ENVIRONMENT=.*/ENVIRONMENT=staging/' \
-e 's/^REPLICAS=.*/REPLICAS=3/' \
-e '/^DEBUG=/d' \
app.env >"$tmp"; then
mv -- "$tmp" app.env
else
status=$?
rm -f -- "$tmp"
exit "$status"
fi
cat app.envVerification checklist
10. Knowledge check
Question 1. What does the g flag do in s///g?
Question 2. Why choose an alternate delimiter?
Question 3. What does -n do?
Question 4. Should general JSON be edited with sed?
11. Summary
sed excels at line-oriented substitutions, deletions, and addressed edits. Keep variable interpolation boundaries explicit, avoid portability surprises around in-place editing, and use structured parsers for structured data.
12. Further reading
- GNU sed manual.
- POSIX sed utility specification.
- BSD/macOS sed manual pages.
- ShellCheck documentation on shell quoting around sed.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.