sed Cheat Sheet

Most used
sed 's/old/new/g' file              # replace all, print result
sed -i 's/old/new/g' file           # replace all, edit file in place
sed -i.bak 's/old/new/g' file       # same, keep file.bak
sed '/pattern/d' file               # delete lines matching pattern
sed -n '10,20p' file                # print only lines 10-20
sed -E 's/([0-9]+)px/\1rem/g' file  # extended regex with capture group

sed reads input line by line, applies a script to each line and prints the result. Nothing changes on disk unless you use -i. Syntax: sed [options] 'script' [file...]. This page covers GNU sed, the version on every mainstream Linux distro; check with sed --version. Combine it with grep to find files and awk when you need fields and arithmetic.

Substitution

CommandWhat it does
sed 's/a/b/' fReplace the first a on each line
sed 's/a/b/g' fReplace every a on each line
sed 's/a/b/2' fReplace only the 2nd occurrence on each line
sed 's/a/b/2g' fReplace the 2nd and all later occurrences
sed 's/a/b/I' fCase-insensitive match (GNU extension)
sed 's|/old/path|/new/path|g' fUse | as delimiter to avoid escaping slashes
sed 's/.*/"&"/' f& inserts the whole match (wraps each line in quotes)
sed 's/\(key\)=\(.*\)/\2=\1/' fBRE capture groups \( \), reused as \1 \2
sed -E 's/(key)=(.*)/\2=\1/' fSame with extended regex, no escaping of parentheses
sed 's/[a-z]*/\U&/' fUppercase the match (\U, \L, \u, \l, \E are GNU)
sed -n 's/a/b/p' fPrint only lines where a substitution happened
sed 's/a/b/w changed.txt' fAlso write changed lines to a file
sed -e 's/a/b/' -e 's/c/d/' fRun several commands (or separate them with ;)

Addresses: choosing which lines

Any command can be prefixed with an address. Without one it applies to every line.

CommandWhat it does
sed '5s/a/b/' fOnly line 5
sed '$s/a/b/' fOnly the last line
sed '10,20s/a/b/' fLines 10 to 20
sed '/start/,/end/s/a/b/' fFrom a line matching start to the next matching end
sed '/^#/!s/a/b/' f! negates: every line that is not a comment
sed '1~2s/a/b/' fEvery 2nd line starting at 1 (odd lines, GNU)
sed '/start/,+3d' fMatching line plus the next 3 (GNU)
sed '0,/foo/s//bar/' fReplace only the first foo in the whole file (GNU)

Deleting and printing lines

CommandWhat it does
sed '3d' fDelete line 3
sed '$d' fDelete the last line
sed '/^$/d' fDelete empty lines
sed '/^\s*#/d' fDelete comment lines (including indented ones)
sed '/^\s*$/d' fDelete blank and whitespace-only lines
sed '1,5d' fDelete lines 1 to 5
sed -n '5p' fPrint only line 5 (-n turns off automatic printing)
sed -n '/start/,/end/p' fPrint a block between two patterns
sed -n '$p' fPrint the last line
sed '20q' fPrint the first 20 lines then quit (like head -20, stops reading early)
sed -n '/pattern/=' fPrint line numbers of matching lines

Inserting, appending and changing lines

CommandWhat it does
sed '1i\# header' fInsert a line before line 1
sed '$a\last line' fAppend a line after the last line
sed '/pattern/a\new line' fAppend after every matching line
sed '/pattern/i\new line' fInsert before every matching line
sed '/^Port /c\Port 2222' fReplace the whole matching line
sed '/pattern/r other.txt' fInsert the contents of a file after matching lines
sed 'G' fDouble-space a file (append the empty hold space)
sed '=' f | sed 'N;s/\n/ /'Number every line

Options

CommandWhat it does
sed -i ...Edit files in place (GNU: no argument needed)
sed -i.bak ...Edit in place and keep a backup with that suffix
sed -n ...Do not print lines automatically; use p to print
sed -E ...Extended regex (-r is the older GNU spelling)
sed -f script.sed fRead the sed script from a file
sed -s ...Treat multiple files separately (so $ means each file's last line)
sed -z ...Lines are separated by NUL instead of newline (lets you match across newlines)
sed --debug ...Show how sed parses and runs the script (GNU 4.6+)

Common recipes

Change a setting in a config file and keep a backup (here, the SSH port; see the SSH cheat sheet before restarting sshd):

sudo sed -i.bak -E 's/^#?Port .*/Port 2222/' /etc/ssh/sshd_config
diff /etc/ssh/sshd_config.bak /etc/ssh/sshd_config

Preview a change first, then apply it:

sed 's/http:/https:/g' site.conf | diff site.conf -
sed -i 's/http:/https:/g' site.conf

Replace across many files found by find:

find . -name '*.md' -type f -exec sed -i 's/linuxtoday\.com/linuxtoday.net/g' {} +

Strip trailing whitespace and Windows line endings:

sed -i 's/[[:space:]]*$//' file.txt
sed -i 's/\r$//' script.sh     # fixes "/bin/bash^M: bad interpreter"

Use a shell variable in the replacement (double quotes, and a delimiter that cannot appear in the value):

new_dir="/srv/www"
sed -i "s|^root .*|root $new_dir;|" site.conf

Print a section of a log between two timestamps:

sed -n '/^2026-10-16 09:00/,/^2026-10-16 09:30/p' app.log

Join all lines into one, comma-separated:

sed -z 's/\n/,/g; s/,$/\n/' list.txt

Uncomment a line:

sudo sed -i 's/^#\s*\(PermitRootLogin\)/\1/' /etc/ssh/sshd_config

Gotchas

  • GNU vs BSD sed -i. GNU sed (Linux) takes -i or -i.bak. BSD sed (macOS, FreeBSD) requires an argument: sed -i '' 's/a/b/' f. On GNU, sed -i '' ... treats '' as the script and fails. A portable form is sed -i.bak ... && rm f.bak.
  • -i replaces the file. sed writes a new file and renames it, so hard links are broken, a symlink is replaced by a regular file unless you add --follow-symlinks, and ownership can change if you run it as another user.
  • Don't combine flags as -ie. GNU sed reads -ie as "in place with backup suffix e" and leaves filee files behind. Write -i -e or -Ei.
  • Escape the regex, not just the delimiter. . matches any character, so s/1.2.3.4/x/ also matches 1a2b3c4. Use 1\.2\.3\.4. In the replacement, & and \ are special.
  • sed works line by line. A pattern containing \n won't match across lines unless you use -z or the N command.
  • \s, \+, \? and I are GNU extensions. They work on Linux but not in strict POSIX or BusyBox sed in every case; use [[:space:]] and -E for portability.
  • Single quotes stop variable expansion. sed 's/x/$HOME/' inserts the literal text $HOME. Use double quotes when you need a variable.

Reference: the GNU sed manual. For editing in scripts, see the bash scripting tutorial.

Frequently asked questions

How do I replace a string in a file with sed?

Use sed -i 's/old/new/g' file. -i edits the file in place and g replaces every occurrence on each line, not just the first.

How do I make a backup when using sed -i?

Give -i a suffix with no space: sed -i.bak 's/a/b/' file keeps the original as file.bak.

How do I use a slash in a sed replacement?

Pick a different delimiter, for example sed 's|/usr/local|/opt|g'. Any character after s becomes the delimiter.

How do I delete a line containing a word with sed?

Use sed '/word/d' file to print the result, or sed -i '/word/d' file to change the file.

Why does sed -i fail on macOS?

BSD sed on macOS requires an argument after -i, so use sed -i '' 's/a/b/' file there. GNU sed on Linux takes -i alone.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.