sed (stream editor) processes text line by line, applying transformations as data flows through. It’s the scalpel to awk’s Swiss army knife β focused on text substitution and line manipulation.
Basic Substitution#
1
2
3
4
5
6
7
8
9
10
11
| # Replace first occurrence per line
sed 's/old/new/' file.txt
# Replace all occurrences per line
sed 's/old/new/g' file.txt
# Case insensitive
sed 's/old/new/gi' file.txt
# Replace Nth occurrence
sed 's/old/new/2' file.txt # Second occurrence only
|
Delimiters#
When patterns contain slashes, use different delimiters:
1
2
3
4
5
6
7
| # Default slash
sed 's/\/path\/to\/file/\/new\/path/' file.txt
# Better: use different delimiter
sed 's|/path/to/file|/new/path|g' file.txt
sed 's#/path/to/file#/new/path#g' file.txt
sed 's@/path/to/file@/new/path@g' file.txt
|
In-Place Editing#
1
2
3
4
5
6
7
8
| # Edit file directly (creates backup)
sed -i.bak 's/old/new/g' file.txt
# Edit without backup (careful!)
sed -i 's/old/new/g' file.txt
# macOS requires empty string for no backup
sed -i '' 's/old/new/g' file.txt
|
Line Selection#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Specific line number
sed '5s/old/new/' file.txt
# Range of lines
sed '5,10s/old/new/g' file.txt
# From line to end
sed '5,$s/old/new/g' file.txt
# Lines matching pattern
sed '/pattern/s/old/new/g' file.txt
# Lines between patterns
sed '/start/,/end/s/old/new/g' file.txt
|
Delete Lines#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Delete specific line
sed '5d' file.txt
# Delete range
sed '5,10d' file.txt
# Delete lines matching pattern
sed '/pattern/d' file.txt
# Delete empty lines
sed '/^$/d' file.txt
# Delete lines NOT matching pattern
sed '/pattern/!d' file.txt
|
Insert and Append#
1
2
3
4
5
6
7
8
9
10
11
| # Insert before line 5
sed '5i\New line before' file.txt
# Append after line 5
sed '5a\New line after' file.txt
# Insert before pattern
sed '/pattern/i\New line' file.txt
# Append after pattern
sed '/pattern/a\New line' file.txt
|
Print Lines#
1
2
3
4
5
6
7
8
9
10
11
12
| # Print only matching lines (like grep)
sed -n '/pattern/p' file.txt
# Print line numbers
sed -n '5p' file.txt
sed -n '5,10p' file.txt
# Print first 10 lines (like head)
sed -n '1,10p' file.txt
# Print last line
sed -n '$p' file.txt
|
Regular Expressions#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # Word boundaries
sed 's/\bword\b/replacement/g' file.txt
# Start/end of line
sed 's/^/PREFIX: /' file.txt # Add prefix
sed 's/$/ SUFFIX/' file.txt # Add suffix
# Character classes
sed 's/[0-9]/#/g' file.txt # Replace digits
sed 's/[a-zA-Z]/?/g' file.txt # Replace letters
# Quantifiers
sed 's/o*/X/g' file.txt # Zero or more
sed 's/o\+/X/g' file.txt # One or more (extended)
sed 's/o\?/X/g' file.txt # Zero or one (extended)
|
Extended Regex#
1
2
3
| # Use -E for extended regex (cleaner syntax)
sed -E 's/[0-9]+/NUM/g' file.txt
sed -E 's/(foo|bar)/baz/g' file.txt
|
Capture Groups#
1
2
3
4
5
6
7
8
9
10
11
| # Basic capture and reference
sed 's/\(pattern\)/[\1]/g' file.txt
# Extended regex (cleaner)
sed -E 's/(pattern)/[\1]/g' file.txt
# Multiple groups
sed -E 's/([a-z]+) ([0-9]+)/\2-\1/g' file.txt
# Swap words
sed -E 's/(\w+) (\w+)/\2 \1/' file.txt
|
Multiple Commands#
1
2
3
4
5
6
7
8
| # Semicolon separator
sed 's/foo/bar/g; s/baz/qux/g' file.txt
# -e flag
sed -e 's/foo/bar/g' -e 's/baz/qux/g' file.txt
# Script file
sed -f script.sed file.txt
|
Practical Examples#
Config File Editing#
1
2
3
4
5
6
7
8
9
10
11
| # Change config value
sed -i 's/^DEBUG=.*/DEBUG=true/' config.env
# Comment out line
sed -i 's/^FEATURE_X/# FEATURE_X/' config.env
# Uncomment line
sed -i 's/^# \(FEATURE_X\)/\1/' config.env
# Add line after match
sed -i '/\[section\]/a new_key=value' config.ini
|
Log Processing#
1
2
3
4
5
6
7
8
9
| # Remove timestamps
sed 's/^[0-9-]* [0-9:]*,*[0-9]* //' app.log
# Extract between delimiters
sed -n 's/.*START\(.*\)END.*/\1/p' file.txt
# Mask sensitive data
sed 's/password=[^ ]*/password=REDACTED/g' log.txt
sed -E 's/[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}/XXXX-XXXX-XXXX-XXXX/g' log.txt
|
1
2
3
4
5
6
7
8
9
10
11
| # Update import statements
sed -i 's/from old_module/from new_module/g' *.py
# Change function calls
sed -i 's/oldFunc(/newFunc(/g' *.js
# Update version strings
sed -i 's/version = "[0-9.]*"/version = "2.0.0"/' setup.py
# Add copyright header
sed -i '1i\# Copyright 2024 Company Inc.' *.py
|
Data Cleanup#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Remove trailing whitespace
sed 's/[[:space:]]*$//' file.txt
# Remove leading whitespace
sed 's/^[[:space:]]*//' file.txt
# Squeeze multiple spaces to one
sed 's/ */ /g' file.txt
# Convert DOS to Unix line endings
sed 's/\r$//' file.txt
# Remove blank lines
sed '/^[[:space:]]*$/d' file.txt
|
JSON/XML Manipulation#
1
2
3
4
5
6
7
8
| # Simple value replacement (not for complex JSON)
sed 's/"name": "[^"]*"/"name": "newvalue"/' file.json
# Change XML attribute
sed 's/id="[^"]*"/id="newid"/g' file.xml
# Remove XML tags
sed 's/<[^>]*>//g' file.xml
|
Hold Space (Advanced)#
sed has a pattern space (current line) and hold space (buffer):
1
2
3
4
5
6
7
8
| # Join every two lines
sed 'N;s/\n/ /' file.txt
# Reverse line order
sed -n '1!G;h;$p' file.txt
# Print line and the one before it
sed -n '/pattern/{x;p;x;p}' file.txt
|
Common Patterns#
1
2
3
4
5
6
7
8
9
10
11
| # Remove HTML tags
sed 's/<[^>]*>//g' file.html
# Extract email addresses
sed -n 's/.*\([a-zA-Z0-9._%+-]*@[a-zA-Z0-9.-]*\.[a-zA-Z]*\).*/\1/p' file.txt
# Format phone numbers
sed -E 's/([0-9]{3})([0-9]{3})([0-9]{4})/(\1) \2-\3/g' file.txt
# Convert camelCase to snake_case
sed -E 's/([a-z])([A-Z])/\1_\L\2/g' file.txt
|
1
2
3
4
5
6
7
8
| # Use sed in pipeline
cat file.txt | sed 's/old/new/g' | grep pattern
# Process find results
find . -name "*.txt" -exec sed -i 's/old/new/g' {} \;
# With xargs
echo "file1.txt file2.txt" | xargs sed -i 's/old/new/g'
|
Quick Reference#
| Task | Command |
|---|
| Replace first | sed 's/old/new/' |
| Replace all | sed 's/old/new/g' |
| Delete line | sed 'Nd' |
| Delete pattern | sed '/pattern/d' |
| Print matches | sed -n '/pattern/p' |
| In-place edit | sed -i 's/old/new/g' |
| Insert before | sed 'Ni\text' |
| Append after | sed 'Na\text' |
| Line range | sed 'N,Ms/old/new/g' |
| Capture group | sed 's/\(pat\)/[\1]/' |
sed excels at surgical text changes β replacing patterns, deleting lines, inserting text. For complex logic or field-based processing, reach for awk. For simple searches, use grep. Together, these three tools handle most text processing needs.
π¬ Get the Newsletter
Weekly insights on DevOps, automation, and CLI mastery. No spam, unsubscribe anytime.