sed, the stream editor, reads text line by line, changes it according to your rules and writes the result out. For system administrators it is the quickest way to fix a setting in a configuration file, remove a bad line or change the same value across many files, all from a shell and without opening an editor. This guide covers the commands you will use most, with real troubleshooting examples and the safety habits that stop a one-line fix from becoming an outage.
Preview every change first by running sed without -i, then edit in place with a backup: sed -i.bak 's/old/new/g' file. Use a different delimiter such as | for paths, address lines by number or pattern, and check the result with diff and the service's own config test before you reload anything. The server-configuration examples here are for your own VPS or server; on shared hosting you can only edit files in your own account.
Examples that edit files under /etc or /var/named need root access, so they apply to your own VPS or server only. On shared hosting the server configuration is managed for you, and you can use sed only on files inside your own account, and only if SSH is enabled for it (see section 8).
1. How sed works, and the options you need
sed reads each input line into a buffer, runs your commands on it and prints the buffer. The original file is not touched unless you ask for an in-place edit.
| Option | What it does | Typical use |
|---|---|---|
| -n | Do not print lines automatically; print only what p asks for | Showing just the matching lines |
| -i[SUFFIX] | Edit the file in place, keeping a backup with SUFFIX if given | Applying a tested fix: -i.bak |
| -E | Use extended regular expressions (+, ?, () and {} without backslashes) | Readable patterns |
| -e | Add another command | Several edits in one run |
| -s | Treat several files as separate, not one long stream | Line numbers and ranges per file |
The examples use GNU sed, the version on Linux servers. On macOS and BSD, -i needs an explicit suffix argument: sed -i '' 's/a/b/' file edits without a backup.
2. Find and replace
The substitute command is s/pattern/replacement/flags:
# Preview: replace every "old_value" with "new_value" and print the result
sed 's/old_value/new_value/g' app.conf
# Only the first match on each line (no g flag)
sed 's/foo/bar/' app.conf
# Case-insensitive match (GNU)
sed 's/listen 80/listen 8080/I' site.confWhen the text contains slashes, such as file paths, change the delimiter instead of escaping every /:
sed -i.bak 's|/var/www/old-site|/var/www/new-site|g' /etc/nginx/conf.d/site.confSpecial characters in the pattern (., *, [, ^, $) are regular-expression syntax. To match a literal dot, as in an IP address, escape it: s/192\.0\.2\.10/192.0.2.20/g. In the replacement, & means "the whole match", so s/[0-9]+/[&]/ with -E wraps numbers in brackets.
3. Edit in place safely
- Preview. Run the command without
-iand read the output, or pipe it todiff: `sed 's/old/new/g' app.confdiff app.conf -`. - Apply with a backup.
sed -i.bak 's/old/new/g' app.confwrites the change and keeps the original asapp.conf.bak. - Compare.
diff app.conf.bak app.confshows exactly what changed. - Test the service's config.For example
nginx -t,apachectl configtest,named-checkconforsshd -t. - Reload, or roll back.Reload only if the test passes. Otherwise restore with
mv app.conf.bak app.conf.
A common mistake is sed 's/old/new/g' app.conf > app.conf.bak. That writes the changed text to the backup and leaves the original unchanged. Worse, sed ... app.conf > app.conf empties the file before sed reads it. Use -i.bak, or cp the file first.
Be aware that sed -i replaces the file with a new one. If the path is a symbolic link, GNU sed replaces the link with a regular file unless you add --follow-symlinks. File ownership can also change if you run it as a different user.
4. Select exactly the lines you want
Commands can be limited to line numbers, patterns or ranges:
# Print only lines 10 to 20
sed -n '10,20p' /var/log/app.log
# Print lines that match, like grep
sed -n '/ERROR/p' /var/log/app.log
# Replace only on lines containing "upstream"
sed -i.bak '/upstream/ s/127\.0\.0\.1/10.0.0.5/' site.conf
# Delete a matching line and the 5 lines after it (GNU)
sed -i.bak '/^# BEGIN old-block/,+5d' app.conf
# Delete from one marker to another, markers included
sed -i.bak '/^# BEGIN legacy/,/^# END legacy/d' app.confOther useful commands:
# Comment out a setting instead of deleting it
sed -i.bak 's/^\(PermitRootLogin.*\)/# \1/' /etc/ssh/sshd_config
# Append a line after a match, or insert one before it (GNU)
sed -i.bak '/^\[mysqld\]/a max_connections = 200' /etc/my.cnf.d/server.cnf
sed -i.bak '/^Include/i # Local overrides below' app.conf
# Strip Windows line endings from an uploaded script
sed -i 's/\r$//' deploy.sh
# Remove trailing spaces and blank lines
sed -i.bak -e 's/[[:space:]]*$//' -e '/^$/d' list.txtCommenting a line out keeps the old value in the file, so rolling back is easy.
5. Real-world troubleshooting examples
Remove a stale zone from a BIND configuration
On your own DNS server, a zone block for a domain you no longer host can stop named from loading. Assuming the block ends with a }; line of its own:
sed -n '/^zone "oldzone.com"/,/^};/p' /etc/named.conf # check what will go
sed -i.bak '/^zone "oldzone.com"/,/^};/d' /etc/named.conf
named-checkconf && systemctl reload namedThe range stops at the first }; it finds. If the zone block contains nested braces, print it first (as above) and check it matches what you expect.
Update a server IP address across many files
grep -rl '192\.0\.2\.10' /etc/nginx/conf.d/ # list the files first
grep -rlZ '192\.0\.2\.10' /etc/nginx/conf.d/ | xargs -0 sed -i.bak 's/192\.0\.2\.10/192.0.2.20/g'
nginx -t && systemctl reload nginxListing with grep -l first means sed only touches files that need the change, and -Z with xargs -0 handles file names with spaces.
Remove a record from many zone files
for f in /var/named/*.db; do
sed -i.bak '/unwanted-record/d' "$f"
doneZone files also carry a serial number. After changing records by hand, increase each zone's serial, then run named-checkzone and reload, or secondary servers will not pick up the change.
6. Debugging sed commands
- Build the command up in steps. Run each expression on its own without
-i, check the output, then combine them with-e. - Use
-nwithpto see only the lines a pattern matches before you change them. - Watch the quoting. Use single quotes around the script so the shell does not expand
$or!. If you need a shell variable, close the quotes around it:sed "s|$OLD|$NEW|g", and remember the variable's contents are then treated as a pattern. - Remember that sed works line by line. Patterns do not match across line breaks unless you use advanced commands; for multi-line or structured files, a proper tool is safer.
7. When to use something other than sed
sed is ideal for line-based text. For structured formats, use a parser: jq for JSON and yq for YAML, because a regex can break quoting or nesting. For larger scripted changes, awk, perl -pi -e or a configuration management tool such as Ansible is easier to read and repeat. Our guide to editing files over SSH with sed, perl and other tools compares the options.
8. Running this on Domain India
On a VPS, you have root access and all the examples above apply. Our VPS plans are self-managed: you run the operating system, updates and backups yourself.
- 1 vCPU
- 2 GB DDR4 RAM
- 64 GB NVMe SSD Storage
- 2 TB Monthly Bandwidth
On shared hosting (cPanel, DirectAdmin or Webuzo), jailed SSH is available on every plan. It is off by default; ask support to enable it for your account, and log in with an SSH key. Inside the jail you can edit files in your own home folder, such as .htaccess, wp-config.php or your app's .env, but not server configuration. Tools available inside the jailed shell vary, so ask support if a command is missing. See enabling and accessing jailed SSH.
How do I make sed keep a backup when editing a file?
Add a suffix to the -i option, for example sed -i.bak 's/old/new/g' file. The original is saved as file.bak and the edited version replaces file.
How do I replace text that contains slashes, such as a file path?
Use a different delimiter in the s command, such as a pipe: sed 's|/old/path|/new/path|g' file. Any character that does not appear in the pattern works.
How can I test a sed command without changing the file?
Run it without -i. sed then prints the changed text to the screen and leaves the file alone. Piping that output to diff file - shows only the lines that would change.
Why does sed -i fail on macOS?
macOS uses BSD sed, where -i needs an explicit suffix argument. Use sed -i '' 's/a/b/' file for no backup, or sed -i.bak 's/a/b/' file for a backup.
Can I use sed on shared hosting?
Only on files in your own account, and only if SSH is enabled for it. Jailed SSH is available on every Domain India shared hosting plan on request, with key login. Server configuration files cannot be changed on shared hosting.
Ready to put this to work? Compare VPS plans for full root access, or open a support ticket to have jailed SSH enabled on your shared hosting account.
A self-managed VPS gives you root access to edit any configuration file, with the operating system and updates in your hands.
See VPS plans