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
 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

Code Transformation

 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

Combining with Other Tools

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

TaskCommand
Replace firstsed 's/old/new/'
Replace allsed 's/old/new/g'
Delete linesed 'Nd'
Delete patternsed '/pattern/d'
Print matchessed -n '/pattern/p'
In-place editsed -i 's/old/new/g'
Insert beforesed 'Ni\text'
Append aftersed 'Na\text'
Line rangesed 'N,Ms/old/new/g'
Capture groupsed '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.