sed: edit text with commands

Updated November 2026

sed, the stream editor, changes text as it flows through: replace words, delete lines, insert text. It is the standard way to edit configuration files from scripts.

sed [options] 'commands' [file ...] sed -i[suffix] 'commands' file ... # edit files in place

Find and replace

sed 's/http:/https:/' page.html          # first match on each line
sed 's/http:/https:/g' page.html         # every match (g = global)
sed 's/colour/color/gi' notes.txt        # ignore case (GNU, FreeBSD, macOS)
sed 's|/var/www|/srv/www|g' site.conf    # another delimiter when the text has slashes
sed 's/^/# /' script.sh                  # put "# " at the start of every line
sed 's/[[:space:]]*$//' file.txt         # remove trailing spaces

Without -i, sed prints the result and leaves the file unchanged, which is a safe way to test.

Edit files in place

sed -i.bak 's/^Port 22$/Port 2222/' /etc/ssh/sshd_config   # keep sshd_config.bak
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
macOS and BSD

BSD sed needs an argument after -i: use sed -i '' 's/a/b/' file for no backup, or sed -i.bak, which works on both GNU and BSD.

Delete and print lines

sed '/^#/d' app.conf                    # delete comment lines
sed '/^$/d' file.txt                    # delete empty lines
sed '1d' data.csv                       # delete the header line
sed -n '10,20p' file.txt                # print only lines 10-20
sed -n '/BEGIN/,/END/p' file.txt        # print from a BEGIN line to an END line
sed '$d' file.txt                       # delete the last line
sed -n '$p' file.txt                    # print the last line

Insert and append

sed '1i # managed by Ansible' app.conf          # insert before line 1 (GNU one-line form)
sed '/^\[mysqld\]/a bind-address = 127.0.0.1' my.cnf   # add a line after a match

Groups and back-references

echo "2026-11-02" | sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3.\2.\1/'   # 02.11.2026
sed -E 's/^([^=]+)=(.*)/\1="\2"/' vars.env          # quote values
echo "Hello World" | sed 's/\w\+/[&]/g'           # & is the whole match: [Hello] [World]

-E (or -r on older GNU sed) enables extended regular expressions, so parentheses and + work without backslashes.

Several commands

sed -e 's/foo/bar/g' -e '/^$/d' input.txt
sed -f fixes.sed input.txt              # commands from a file

When to use something else

sed works line by line. For column-based data use awk; for multi-line or complex replacements, a Perl one-liner (perl -pi -e) or a small script is clearer. See Perl basics.