Find and Replace with sed

sed: the stream editor

sed edits text as it flows past, without opening an editor. Its most famous command is s, substitute: s/old/new/.

cat app.conf
sed 's/8080/9090/' app.conf

In the terminal

student@vulntech:~$ cat app.conf
# Treasure tracker settings
host=localhost
port=8080
debug=true
# who to call
admin=captain@old-ship.example
backup=mate@old-ship.example
student@vulntech:~$ sed 's/8080/9090/' app.conf
# Treasure tracker settings
host=localhost
port=9090
debug=true
# who to call
admin=captain@old-ship.example
backup=mate@old-ship.example

By itself, sed only prints the changed text: the file is untouched. Check with grep:

grep port app.conf

In the terminal

student@vulntech:~$ grep port app.conf
port=8080

Every match: the g flag

s replaces only the first match on each line. Add g (global) to replace them all:

echo "red red red" | sed 's/red/blue/'
echo "red red red" | sed 's/red/blue/g'

In the terminal

student@vulntech:~$ echo "red red red" | sed 's/red/blue/'
blue red red
student@vulntech:~$ echo "red red red" | sed 's/red/blue/g'
blue blue blue

Changing the file: -i

-i (in place) writes the changes back into the file. -i.bak keeps a copy of the original first:

sed -i.bak 's/debug=true/debug=false/' app.conf
grep debug app.conf app.conf.bak

In the terminal

student@vulntech:~$ sed -i.bak 's/debug=true/debug=false/' app.conf
student@vulntech:~$ grep debug app.conf app.conf.bak
app.conf:debug=false
app.conf.bak:debug=true

Common mistake: sed -i has no undo. Run the command without -i first, check the output, then add -i.

Deleting and printing lines

CommandWhat it does
sed '/^#/d'Delete the lines that match (here: comments)
sed '/^$/d'Delete empty lines
sed -n '2,4p'Print only lines 2 to 4 (-n = don't print the rest)
sed '3d'Delete line 3
sed '/^#/d' app.conf
sed -n '2,4p' app.conf

In the terminal

student@vulntech:~$ sed '/^#/d' app.conf
host=localhost
port=8080
debug=true
admin=captain@old-ship.example
backup=mate@old-ship.example
student@vulntech:~$ sed -n '2,4p' app.conf
host=localhost
port=8080
debug=true

Paths: pick another separator

When the text has slashes in it, use another character after s, such as |, so you don't have to escape every /:

echo /var/www/site | sed 's|/var/www|/srv/www|'

In the terminal

student@vulntech:~$ echo /var/www/site | sed 's|/var/www|/srv/www|'
/srv/www/site

Remember: sed 's/old/new/g' file shows the result, -i changes the file, /pattern/d deletes lines and -n '2,4p' prints lines 2 to 4.

HOME LEARN COMMUNITY DASHBOARD
Practice terminal Starting…