sed Cheat Sheet
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
| Command | What it does |
|---|---|
sed 's/a/b/' f | Replace the first a on each line |
sed 's/a/b/g' f | Replace every a on each line |
sed 's/a/b/2' f | Replace only the 2nd occurrence on each line |
sed 's/a/b/2g' f | Replace the 2nd and all later occurrences |
sed 's/a/b/I' f | Case-insensitive match (GNU extension) |
sed 's|/old/path|/new/path|g' f | Use | as delimiter to avoid escaping slashes |
sed 's/.*/"&"/' f | & inserts the whole match (wraps each line in quotes) |
sed 's/\(key\)=\(.*\)/\2=\1/' f | BRE capture groups \( \), reused as \1 \2 |
sed -E 's/(key)=(.*)/\2=\1/' f | Same with extended regex, no escaping of parentheses |
sed 's/[a-z]*/\U&/' f | Uppercase the match (\U, \L, \u, \l, \E are GNU) |
sed -n 's/a/b/p' f | Print only lines where a substitution happened |
sed 's/a/b/w changed.txt' f | Also write changed lines to a file |
sed -e 's/a/b/' -e 's/c/d/' f | Run 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.
| Command | What it does |
|---|---|
sed '5s/a/b/' f | Only line 5 |
sed '$s/a/b/' f | Only the last line |
sed '10,20s/a/b/' f | Lines 10 to 20 |
sed '/start/,/end/s/a/b/' f | From 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/' f | Every 2nd line starting at 1 (odd lines, GNU) |
sed '/start/,+3d' f | Matching line plus the next 3 (GNU) |
sed '0,/foo/s//bar/' f | Replace only the first foo in the whole file (GNU) |
Deleting and printing lines
| Command | What it does |
|---|---|
sed '3d' f | Delete line 3 |
sed '$d' f | Delete the last line |
sed '/^$/d' f | Delete empty lines |
sed '/^\s*#/d' f | Delete comment lines (including indented ones) |
sed '/^\s*$/d' f | Delete blank and whitespace-only lines |
sed '1,5d' f | Delete lines 1 to 5 |
sed -n '5p' f | Print only line 5 (-n turns off automatic printing) |
sed -n '/start/,/end/p' f | Print a block between two patterns |
sed -n '$p' f | Print the last line |
sed '20q' f | Print the first 20 lines then quit (like head -20, stops reading early) |
sed -n '/pattern/=' f | Print line numbers of matching lines |
Inserting, appending and changing lines
| Command | What it does |
|---|---|
sed '1i\# header' f | Insert a line before line 1 |
sed '$a\last line' f | Append a line after the last line |
sed '/pattern/a\new line' f | Append after every matching line |
sed '/pattern/i\new line' f | Insert before every matching line |
sed '/^Port /c\Port 2222' f | Replace the whole matching line |
sed '/pattern/r other.txt' f | Insert the contents of a file after matching lines |
sed 'G' f | Double-space a file (append the empty hold space) |
sed '=' f | sed 'N;s/\n/ /' | Number every line |
Options
| Command | What 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 f | Read 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-ior-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 issed -i.bak ... && rm f.bak. -ireplaces 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-ieas "in place with backup suffixe" and leavesfileefiles behind. Write-i -eor-Ei. - Escape the regex, not just the delimiter.
.matches any character, sos/1.2.3.4/x/also matches 1a2b3c4. Use1\.2\.3\.4. In the replacement,&and\are special. - sed works line by line. A pattern containing
\nwon't match across lines unless you use-zor theNcommand. \s,\+,\?andIare GNU extensions. They work on Linux but not in strict POSIX or BusyBox sed in every case; use[[:space:]]and-Efor 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.