sed substitutes text in a file without opening it. Learn the `s/old/new/` form, how `-i` edits the file itself, and how to select or delete lines, by running the commands in a real terminal in your browser.
Updated: 2026-09-06
sed [options] 'script' file...
The script you will use most is s/old/new/, a substitution.
Look at what you are about to change.
$ cat config.yml
port: 3000
host: localhost
debug: false
Replace localhost.
$ sed 's/localhost/example.com/' config.yml
port: 3000
host: example.com
debug: false
There is the result. The file, however, has not changed.
$ cat config.yml
port: 3000
host: localhost
debug: false
By default sed only prints. That is what makes it safe to try against a production config before committing to anything.
Once you have seen the result, add -i.
$ sed -i 's/localhost/example.com/' config.yml
$ cat config.yml
port: 3000
host: example.com
debug: false
-i is short for in place.
Add a suffix to keep a copy of what was there before.
$ sed -i.bak 's/3000/8080/' config.yml
$ ls
config.yml config.yml.bak logs/ urls.txt
$ cat config.yml.bak
port: 3000
host: example.com
debug: false
config.yml.bak is the copy.
Make it a habit on servers and you always have a way back.
By default only the first match on each line is replaced.
$ cat urls.txt
api=http://example.com cdn=http://cdn.example.com
$ sed 's/http:/https:/' urls.txt
api=https://example.com cdn=http://cdn.example.com
The second one survived.
g at the end replaces all of them.
$ sed 's/http:/https:/g' urls.txt
api=https://example.com cdn=https://cdn.example.com
g stands for global.
Besides substituting, sed can pick lines.
$ sed '/DEBUG/d' logs/app.log
INFO server started
ERROR connection refused
INFO retrying
ERROR timeout
/DEBUG/d means delete every line containing DEBUG.
Line numbers work too.
$ sed -n '2p' logs/app.log
DEBUG cache warmed
$ sed -n '1,3p' logs/app.log
INFO server started
DEBUG cache warmed
ERROR connection refused
-n turns off the default printing, and p names the lines to print.
sed is what you type for the same edit applied mechanically.
| Situation | What to type |
|---|---|
| Swap a value in a config file | sed -i.bak 's/3000/8080/' config.yml |
| Move every URL to https | sed -i 's/http:/https:/g' urls.txt |
| Read a log without the noise | sed '/DEBUG/d' app.log |
| Pull out a range of lines | sed -n '10,20p' app.log |
| Comment out every line | sed 's/^/# /' config.yml |
^ matches the start of a line and $ the end.
$ sed 's/^/# /' config.yml
# port: 8080
# host: example.com
# debug: false
-i cannot be undone.
The file changes the moment you run it.
Either look at the result without -i first, or use -i.bak so there is a copy.
Change the separator when the text contains /.
Replacing a path means the separators and the content are both slashes, which nobody can read.
The separator does not have to be /, so use # or |.
$ echo /home/user/project | sed 's#/home/user#/srv#'
/srv/project
It works in a pipe.
$ grep ERROR logs/app.log | sed 's/ERROR/failure/'
failure connection refused
failure timeout
A missing file says so.
$ sed 's/nope/x/' nothing.txt
sed: can't read nothing.txt: No such file or directorywebterm.appthis site
Terminal Fundamentals
Learn commonly used commands
learn.webterm.appa separate site

Commands stick when they show up in a real sequence of work, not one at a time. There is a course that builds them up in order.
See the course