sed (stream editor) transforms text line by line: replace words, delete lines, insert text, extract ranges. It’s the go-to tool for editing config files from scripts and for quick bulk replacements across many files.
sed [options] 'SCRIPT' [file...]
By default sed prints the result to standard output and leaves the file unchanged.
Substitute (find and replace)
sed 's/old/new/' file.txt # first occurrence on each line
sed 's/old/new/g' file.txt # all occurrences (global)
sed 's/old/new/2' file.txt # only the 2nd occurrence per line
sed 's/old/new/gi' file.txt # case-insensitive (GNU sed)
Use another delimiter for paths
Slashes in the pattern need escaping — or choose a different delimiter:
sed 's|/var/www/old|/var/www/new|g' nginx.conf
sed 's#http://#https://#g' urls.txt
Edit files in place
sed -i 's/old/new/g' file.txt # edit the file directly
sed -i.bak 's/old/new/g' file.txt # keep a backup as file.txt.bak
Always test without -i first, or use the .bak suffix. On macOS (BSD sed), -i requires an argument: sed -i '' 's/a/b/' file.
Practical config edits
# Change a setting
sudo sed -i 's/^#\?PasswordAuthentication .*/PasswordAuthentication no/' /etc/ssh/sshd_config
# Set PHP limits
sudo sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 64M/' /etc/php/8.3/fpm/php.ini
# Comment out a line
sudo sed -i 's/^bind-address/# bind-address/' /etc/mysql/mariadb.conf.d/50-server.cnf
# Uncomment a line
sed -i 's/^# *\(net.ipv4.ip_forward=1\)/\1/' /etc/sysctl.conf
The ^#\? part matches the line whether or not it’s commented out. After editing service configs, validate them (sshd -t, nginx -t) before reloading.
Delete lines
sed '/^#/d' file # delete comment lines
sed '/^$/d' file # delete empty lines
sed '/^\s*$/d' file # delete blank lines (incl. whitespace)
sed '5d' file # delete line 5
sed '10,20d' file # delete lines 10–20
sed '$d' file # delete the last line
sed '/DEBUG/d' app.log # delete lines containing DEBUG
Show a config file without comments and blank lines:
sed -e '/^\s*#/d' -e '/^\s*$/d' /etc/ssh/sshd_config
Print specific lines
-n suppresses automatic printing; p prints explicitly:
sed -n '10p' file # line 10
sed -n '10,20p' file # lines 10–20
sed -n '/BEGIN/,/END/p' file # from a line matching BEGIN to one matching END
sed -n '/error/p' app.log # like grep
sed -n '$p' file # last line
Extract a time window from a log:
sed -n '/2026-11-04 09:00/,/2026-11-04 10:00/p' app.log
Insert and append
sed '3i\New line before line 3' file
sed '3a\New line after line 3' file
sed '/^\[mysqld\]/a\skip-name-resolve' my.cnf # after a matching line
sed '1i\#!/bin/bash' script.sh # add a first line
Change whole lines
sed '/^Port /c\Port 2222' sshd_config
Regular expressions and groups
By default sed uses basic regex; -E enables extended regex (fewer backslashes):
# Swap "Last, First" to "First Last"
sed -E 's/^([^,]+), (.+)$/\2 \1/' names.txt
# Wrap numbers in brackets
sed -E 's/[0-9]+/[&]/g' file # & = the whole match
# Remove trailing whitespace
sed -i 's/[[:space:]]*$//' file
# Convert Windows line endings
sed -i 's/\r$//' script.sh
The last one fixes the classic /bin/bash^M: bad interpreter error for scripts edited on Windows.
Multiple commands
sed -e 's/foo/bar/g' -e '/^#/d' file
sed 's/foo/bar/g; s/baz/qux/g' file
sed -f script.sed file # commands from a file
Bulk replace across many files
grep -rl 'old.example.com' /var/www/site --include='*.php' | xargs sed -i 's/old\.example\.com/new.example.com/g'
Escape dots in the pattern (\.), otherwise . matches any character. Back up first — and don’t use sed on serialized data in databases (WordPress); use wp search-replace instead.
sed vs awk vs grep
- grep — find lines.
- sed — change lines (substitute, delete, insert).
- awk — work with columns and do calculations — see awk examples.
Quick reference
| Task | Command |
|---|---|
| Replace all | sed 's/a/b/g' |
| In place with backup | sed -i.bak 's/a/b/g' f |
| Delete matching lines | sed '/pat/d' |
| Print line range | sed -n '10,20p' |
| Print between patterns | sed -n '/A/,/B/p' |
| Insert before line | sed '3i\text' |
| Append after match | sed '/pat/a\text' |
| Replace whole line | sed '/pat/c\text' |
| Extended regex | sed -E |
Also see grep examples and the bash scripting tutorial.