What I Wanted to Do

I needed to bulk-replace strings in config files and extract specific lines from log files. I could search with grep just fine, but sed always tripped me up when it came to actual substitutions.

Basic Syntax

sed 's/old/new/g' filename
  • s stands for substitute
  • g is global — replaces all occurrences on each line
  • Without g, only the first match per line is replaced

Common Operations

Substituting Strings

# Replace 'foo' with 'bar' and print to stdout
sed 's/foo/bar/g' config.txt

# Edit the file in-place with -i
sed -i 's/foo/bar/g' config.txt

# macOS requires an empty string after -i
sed -i '' 's/foo/bar/g' config.txt

Creating a Backup While Editing In-Place

# Saves original as config.txt.bak before overwriting
sed -i.bak 's/foo/bar/g' config.txt

Deleting Lines

# Delete line 3
sed '3d' file.txt

# Delete all blank lines
sed '/^$/d' file.txt

# Delete comment lines starting with #
sed '/^#/d' file.txt

Printing Specific Lines

# Print lines 5 through 10
sed -n '5,10p' file.txt

# Print lines matching "error"
sed -n '/error/p' file.txt

Inserting Lines

# Append a line after line 3
sed '3a\inserted text here' file.txt

# Insert a line before line 3
sed '3i\inserted text here' file.txt

Multiple Substitutions at Once

# Use -e to chain multiple expressions
sed -e 's/foo/bar/g' -e 's/old/new/g' file.txt

Replacing Strings That Contain Slashes

When the pattern includes / (e.g. file paths or URLs), swap the delimiter.

# Use | as delimiter instead
sed 's|/old/path|/new/path|g' config.txt

Common Pitfalls

  • Editing in-place with -i is irreversible — always use .bak to keep a backup
  • -i behaves differently on macOS vs Linux; macOS requires sed -i ''
  • Regex metacharacters (. * [ ]) need to be escaped with a backslash
  • Forgetting the g flag means only the first match per line gets replaced
  • By default sed writes to stdout, not back to the file — use -i to modify in-place

Looking for reliable cloud infrastructure? Check out these developer-friendly services.