Connecting via SSH

Best Ways to Edit Files over SSH (Linux): sed vs Perl and All the Better Options

By the Domain India teamPublished 9 min read
Knowledge base article
Contents (8 sections)

Over SSH you often need to change a line in a configuration file, a .env or a wp-config.php, sometimes in many files at once. sed and perl can do it in one command, but a careless one-liner can also damage every file it touches. This guide shows how to choose the right tool, the safe way to run it, a cookbook of common edits, and when to reach for a structured tool or an editor instead.

Key takeaways

Preview every change before you apply it (run without -i and pipe to diff), keep a backup (-i.bak), and limit the command to exactly the files you mean. Use sed for simple line edits, perl when you need lookarounds, multi-line matches or logic, and a structured tool such as jq, yq or crudini for JSON, YAML and INI files. Never pipe a file through a command and write it back to itself in the same pipeline; write to a temporary file and move it into place.

1. Safety rules for every edit

  1. Preview. Run the command without -i, so it prints the result instead of saving it, and compare: `sed 's/OLD/NEW/g' app.conf
    diff -u app.conf -`.
  2. Back up.
    Add a suffix to -i so the original is kept: sed -i.bak 's/OLD/NEW/g' app.conf leaves app.conf.bak behind.
  3. Scope.
    Select files precisely with find, git ls-files or a named list, never a loose wildcard across a whole tree.
  4. Check the result.
    Run the program's own config test (for example nginx -t or php -l file.php) before you reload or restart anything.
  5. Clean up.
    Delete the .bak files once you're sure; a stray wp-config.php.bak in a web folder can expose passwords.
Don't write a file back to itself in one pipeline

sed 's/a/b/' file | tee file or cat file | sed 's/a/b/' > file can leave you with an empty file, because the shell or tee truncates the file before sed has finished reading it. Use -i, or write to a temporary file and move it: sed 's/a/b/' file > file.tmp && mv file.tmp file. The sponge command from moreutils also does this safely where it is installed.

2. sed or Perl?

Needsedperl
Simple substitution, delete or insert a lineIdealWorks, more typing
Groups and alternationUse sed -EBuilt in
Lookahead, lookbehind, non-greedy matchesNot supportedBuilt in
Changes that span several linesAwkwardEasy with -0777
Arithmetic or conditions on the matchNoYes, with the /e flag
Same -i behaviour on Linux and macOSNo (see section 7)Yes

Rule of thumb: start with sed. Switch to perl as soon as the pattern needs a lookaround, a non-greedy match or more than one line. awk is the better choice for column-based data.

3. The cookbook

Each example shows the sed form and, where it helps, the perl form. Both keep a .bak backup.

Replace a path (use a different delimiter so slashes need no escaping):

bash
sed -i.bak 's|/var/www/app|/srv/app|g' app.conf
perl -pi.bak -e 's|/var/www/app|/srv/app|g' app.conf

Add a line after a match, and delete matching lines:

bash
sed -i.bak '/^\[server\]/a max_connections = 200' app.ini
sed -i.bak '/^#\s*DEBUG/d' app.conf

Comment out and uncomment a directive. Capture groups need -E in sed:

bash
sed -i.bak -E 's/^(Listen 8080)/# \1/' app.conf
sed -i.bak -E 's/^#\s*(Listen 8080)/\1/' app.conf

Set a key to a value, whatever it was before:

bash
sed -i.bak -E 's|^(\s*timeout\s*=\s*).*|\1"60s"|' app.conf
perl -pi.bak -e 's/^(\s*timeout\s*=\s*).*/${1}"60s"/' app.conf

Change a value only inside one section of an INI file:

bash
sed -i.bak '/^\[server\]/,/^\[/ s/^port=.*/port=9090/' app.ini

Insert a block after a heading (multi-line, so Perl):

bash
perl -0777 -pi.bak -e 's/(\[logging\]\n)/$1level = "info"\nformat = "json"\n/' app.ini

Remove Windows line endings before any other edit, since a hidden \r makes patterns fail to match:

bash
sed -i.bak 's/\r$//' script.sh

Change one column with awk (awk has no in-place option, so write a new file):

bash
awk -F'\t' -v OFS='\t' '{ $3 += 10 } 1' input.tsv > output.tsv

4. Structured files: use a parser, not a regex

A regex doesn't understand nesting, quoting or escaping. For structured formats, a tool that parses the file is safer:

FormatToolExample
JSONjqjq '.logging.level = "info"' config.json > config.json.tmp && mv config.json.tmp config.json
YAMLyq (v4)yq -i '.server.port = 9090' config.yaml
INIcrudinicrudini --set app.ini server port 9090
XMLxmlstarletxmlstarlet ed -L -u '/config/server/port' -v 9090 config.xml

jq has no in-place option, so write to a temporary file and move it, as shown. These tools are packages you install on your own server; they are not always present on a shared or minimal system.

For PHP files such as wp-config.php, WordPress users can use WP-CLI, which edits the constants for you: wp config set WP_DEBUG false --raw.

5. Editors: nano, vim and scripted ex

For a single change you can see, an editor is often quicker and safer than a one-liner.

  • nano is the easiest: open with nano -l file to show line numbers, save with Ctrl+O and exit with Ctrl+X. Ctrl+W searches. See Mastering nano for troubleshooting.
  • vim does repeatable edits well: :%s/OLD/NEW/gc replaces with a confirmation at each match.
  • ex, vim's line-editing mode, can run the same commands from a script: ex -sc '%s/OLD/NEW/g|x' app.conf.

6. Many files at once

Select the files first, check the list, then edit:

bash
# 1. See which files match
grep -rl --include='*.conf' 'OLD' config/

# 2. Edit exactly those, handling spaces in names safely
grep -rlZ --include='*.conf' 'OLD' config/ | xargs -0 -r sed -i.bak 's/OLD/NEW/g'

In a Git repository, git ls-files -z '*.conf' | xargs -0 -r sed -i 's/OLD/NEW/g' touches only tracked files, and git diff shows exactly what changed. Commit before you start, and git checkout -- . undoes the edit completely.

For changes across many servers, a configuration tool such as Ansible (lineinfile, blockinfile, template) repeats the same edit reliably and records what it did.

7. Pitfalls

  • Nothing changed. The pattern didn't match. Test it first with grep -n 'pattern' file, and check for \r line endings.
  • Too much changed. Anchor with ^ and $, or use word boundaries (\b in Perl and GNU sed).
  • macOS. BSD sed needs an argument after -i: sed -i '' 's/a/b/' file for no backup. GNU sed on Linux accepts -i alone or -i.bak.
  • Symlinks. sed -i replaces a symlink with a regular file. Use --follow-symlinks (GNU sed) or edit the target path.
  • Ownership. -i writes a new file. Run as root, it can end up owned by root; check with ls -l afterwards.
  • Speed and odd characters. Prefix with LC_ALL=C for byte-wise matching on large or mixed-encoding files, and never run text tools on binary files.

8. Running this on Domain India

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 edit files in your own account only, not server configuration. We checked the jail on our cPanel and DirectAdmin servers on 24 September 2026:

ToolcPanel jailDirectAdmin jail
sed, perl, awkYesYes
nanoYesYes
vimYesNo
diffYesYes
jq, yqNoNo
rsyncNoNo

To deploy many files, pack them into an archive, copy it with scp or SFTP, and unpack it with tar. Details are in Enabling and accessing jailed SSH.

On a Domain India VPS you have root access and can install any of the tools above. VPS plans are self-managed: you look after the system, updates and backups yourself. See VPS plans.

VPS Starter
₹552.65/mo + GST
  • 1 vCPU
  • 2 GB DDR4 RAM
  • 64 GB NVMe SSD Storage
  • 2 TB Monthly Bandwidth
See plan details

Prices on the cards exclude 18% GST.

How do I edit a file in place with sed and keep a backup?

Add a suffix to the -i option: sed -i.bak 's/old/new/g' file. The original is saved as file.bak and file holds the edited text.

When should I use Perl instead of sed?

When the pattern needs a lookahead or lookbehind, a non-greedy match, a change spanning several lines, or logic on the matched text. For simple line edits, sed is enough.

How can I preview a sed change without saving it?

Run the command without -i and pipe it to diff: sed 's/old/new/g' file | diff -u file -. Only the lines that would change are shown.

Why did my file become empty after a sed command?

The command probably wrote its output back to the same file in one pipeline, such as with tee or a redirect, which truncates the file before it is read. Use sed -i, or write to a temporary file and move it into place.

What is the safest way to edit a JSON or YAML file from the command line?

Use a parser rather than a regex: jq for JSON, writing to a temporary file and moving it, and yq for YAML. They understand the file's structure, so quoting and nesting stay correct.

Which editing tools are available in Domain India's jailed SSH?

On our cPanel and DirectAdmin servers the jail includes sed, perl, awk, nano and diff; vim is available on cPanel. jq, yq and rsync are not available. Jailed SSH is off by default; ask support to enable it.

Ready to work on your files over SSH? Read Enabling and accessing jailed SSH, learn more sed in Effective troubleshooting with sed, or open a support ticket to have SSH enabled on your account.

Need SSH on your hosting account?

Jailed SSH is available on every shared hosting plan. Ask support to enable it, then log in with your SSH key.

Open a support ticket

Ready when you are

Get VPS from ₹552.65/mo + GST

See plans

Was this article helpful?

Your answer helps us decide what to improve next.

Still need help? Open a support ticket and our team will reply.

Prefer an app? Add this site to your home screen.Get the app