How to Find and Replace Text in a File in Linux
Replace text in one file or across a whole project, safely.
sed edits streams, which makes it perfect for this: describe the change once and it applies to ten thousand lines instantly. The two things that separate a safe replacement from a bad afternoon are previewing before writing, and anchoring the pattern so it only matches what you intend.
Step by step
1 Preview first
$ sed 's/old/new/g' file.txt Without -i, sed prints the result and leaves the file untouched. Read the output, confirm it is what you wanted, then add -i.
2 Replace in place, keeping a backup
$ sed -i.bak 's/old/new/g' file.txt Writes the change and leaves file.txt.bak with the original. On a server config, this two-second insurance has saved countless afternoons.
3 Replace across many files
$ grep -rl "old" src/ | xargs sed -i "s/old/new/g" grep -rl lists only the files that contain the text, xargs feeds them to sed. Efficient and precise: files without a match are never touched.
4 When the text contains slashes
$ sed -i "s|/var/www|/srv/web|g" config.conf Any character can be the delimiter after s. Using | avoids escaping every slash in a path.
5 Anchor it to avoid collateral damage
$ sed -i "s/^PORT=.*/PORT=8080/" .env The ^ anchors to the start of the line, so only the PORT setting changes, not a mention of "PORT" inside a comment.
Tips worth knowing
- Always preview, or use -i.bak. sed is fast enough to ruin a file before you finish reading the command.
- On macOS, BSD sed needs an argument for -i, even an empty one: sed -i '' 's/a/b/' file. Scripts meant for both should use -i.bak.
- For interactive, per-occurrence confirmation, your editor is the better tool. sed is for bulk and for scripts.
- In a git repository, run the replacement and then `git diff`: the safest preview there is.
Frequently asked questions
What does the g at the end do?
It replaces every occurrence on each line. Without it, only the first match per line changes.
How do I replace only in certain lines?
Prefix an address: sed -i "/^server/s/8080/9090/" conf replaces only inside lines starting with "server".
sed or awk for this?
sed for substitution, that is what it is for. awk when you also need columns, conditions or arithmetic.
Can I undo it?
Only if you used -i.bak or the file is in version control. That is precisely why both habits exist.
The commands behind it
Stream-edit text: substitute, delete lines, and edit files in place with -i.
grepFind lines matching a pattern in files or piped input: the workhorse of text search.
xargsTurn a list of items into command arguments: the glue between pipelines and commands.
Concepts involved: Regular expression
Choosing between tools
More how-to guides
See how much space is left, and find out what is using it.
Extract a .tar.gz archiveUnpack tar.gz, tar.bz2, tar.xz and zip archives from the command line.
Free a port that is already in useFind which process holds a port and stop it cleanly.
Make a script executableGive a script permission to run, and understand why it needs it.