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

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

  • Linux
  • Command Line
  • sed