Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

By updated

Improve this page

A port to change in an Nginx configuration, an IP address to update in ten files, a hostname to fix after a server rename: these operations come up constantly in Linux administration. Knowing how to do them fast, without mistakes and without opening a graphical editor, is one of an administrator's basic skills.

This guide covers the three main approaches: non-interactive replacement with sed (the most common in administration), interactive replacement in an editor (nano, vi, vim), and multi-file replacement by combining find and sed.

What you will learn

  • Replace a word or a pattern in a file with sed
  • Check a replacement before applying it
  • Search and replace in nano, vi and vim
  • Apply a replacement to several files at once
  • Choose the right tool for the situation

Which tool for which situation?

Before going into each method, here is the quick decision rule:

SituationRecommended toolWhy
Quick replacement in a configuration filesedA single command, no editor to open
Replacement in a script or a pipelinesedNon-interactive, scriptable
Replacement with line-by-line visual checkvim (:s/.../gc)Confirmation before each replacement
One-off edit of a simple filenanoThe most accessible for a beginner
Mass replacement in 10+ filesfind + sedAutomated, no manual intervention
Large file whose context you need to understandvim or viBuilt-in navigation and search

Non-interactive replacement with sed

sed (stream editor) is the reference tool to change text on the command line. It reads a file line by line, applies a transformation and writes the result. You never leave your terminal.

Basic syntax

Terminal window
sed 's/old/new/' file

This command replaces the first occurrence of old with new on each line, and prints the result on standard output. The original file is not modified.

To replace every occurrence on each line, add the g (global) flag:

Terminal window
sed 's/old/new/g' file

Check before changing

Good practice is to always check the result before touching the file. sed prints the result by default without changing the file: take advantage of it.

  1. See what will change:

    Terminal window
    sed 's/8080/8443/g' /etc/nginx/sites-available/default

    The whole file is shown with the replacements applied. Compare visually.

  2. Target the lines involved:

    Terminal window
    grep -n '8080' /etc/nginx/sites-available/default

    You see the numbers of the lines containing the pattern, useful to check that nothing unwanted will be replaced.

  3. Apply the change:

    Terminal window
    sed -i 's/8080/8443/g' /etc/nginx/sites-available/default

    The -i (in-place) option modifies the file directly.

Concrete administration examples

Change a port:

Terminal window
sed -i 's/^Listen 80$/Listen 8080/' /etc/apache2/ports.conf

The pattern is anchored: ^ for the start of the line, $ for the end. Without these anchors, s/Listen 80/…/ would also change a Listen 8080 line. And the target port must be free: Debian's ports.conf already declares Listen 443 for the SSL module, and changing Listen 80 into Listen 443 there makes Apache reject the configuration (Cannot define multiple Listeners on the same IP:port). Always validate with sudo apache2ctl configtest before reloading.

Replace an IP address:

Terminal window
sed -i 's/\b192\.168\.1\.10\b/192.168.1.20/g' /etc/hosts

The escaped dots (\.) only match a dot, and the \b boundaries prevent touching a longer address. Without them, the line 192.168.1.100 db would become 192.168.1.200 db: it is the trap of the address that contains another one.

Change a configuration setting:

Terminal window
sed -i 's/^#PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config

This last command uncomments and changes the line in a single operation. The ^# means "starts with #" and .* matches the rest of the line. On Debian and Ubuntu, sshd_config first includes the files in /etc/ssh/sshd_config.d/, and the first value read wins: check the value really applied with sudo sshd -T | grep -i permitrootlogin.

Alternative delimiter

When the text contains / (file paths, for example), use another delimiter to avoid unreadable escaping:

Terminal window
# Hard to read
sed -i 's/\/usr\/local\/bin/\/opt\/bin/g' script.sh
# Readable: use | or # as the delimiter
sed -i 's|/usr/local/bin|/opt/bin|g' script.sh

Restrict to some lines

You can limit the replacement to a range of lines or to a pattern:

Terminal window
# Lines 10 to 20 only
sed -i '10,20s/old/new/g' file.conf
# Only the lines containing "server"
sed -i '/server/s/8080/8443/g' nginx.conf

Search and replace in an editor

Nano

In nano, the Ctrl+\ shortcut starts search/replace:

  1. Open the file:

    Terminal window
    nano /etc/hosts
  2. Press Ctrl+\

  3. Type the text to search, then Enter

  4. Type the replacement text, then Enter

  5. For each occurrence, nano asks you: Y (replace), N (skip), A (replace all)

When to use nano: simple file, one-off change, you want to see what you are doing at each step. Full details in the nano guide.

Vi / Vim

In vi or vim, replacement is done from command mode:

:%s/old/new/g # Whole file, every occurrence
:%s/old/new/gc # With confirmation for each occurrence
:10,20s/old/new/g # Lines 10 to 20 only

The % means "the whole file". The c (confirm) flag shows you each occurrence and waits for your answer:

  • y, replace
  • n, skip
  • a, replace all (without asking any more)
  • q, stop

To search without replacing, type /pattern in normal mode, then n for the next occurrence.

When to use vim: complex file, need for visual context, selective replacement with confirmation. Full details in the vi guide and the Vim guide.

Replace across several files

find + sed

To apply a replacement to every file in a directory:

Terminal window
find /etc/nginx/ -name '*.conf' -exec sed -i 's/8080/8443/g' {} +

This command:

  1. finds all the .conf files in /etc/nginx/
  2. applies the sed replacement to each of them

grep + sed in a pipeline

A variant that only targets the files containing the pattern:

Terminal window
grep -rlZ 'old-hostname' /etc/ | xargs -0 sed -i 's/old-hostname/new-hostname/g'

grep -rl lists the files containing the pattern (recursively, names only), and xargs passes each file to sed. The -Z / -0 pair separates the names with a null character: without it, a file named a b.conf is split into two names, and sed answers can't read.

Practical exercise

  1. Create a test file:

    Terminal window
    cat > /tmp/test-config.conf << 'EOF'
    server {
    listen 8080;
    server_name old-server.example.com;
    root /var/www/old-server;
    }
    EOF
  2. Check the content:

    Terminal window
    cat /tmp/test-config.conf
  3. Replace the port with sed (without changing the file):

    Terminal window
    sed 's/8080/443/' /tmp/test-config.conf

    Check that the listen line shows 443.

  4. Replace the hostname (changing the file):

    Terminal window
    sed -i 's/old-server/new-server/g' /tmp/test-config.conf
    cat /tmp/test-config.conf

    Both occurrences of old-server must have been replaced.

  5. Open it in vim and replace with confirmation:

    Terminal window
    vim /tmp/test-config.conf

    Type :%s/new-server/prod-server/gc then approve each occurrence with y.

Troubleshooting

SymptomLikely causeSolution
sed replaces nothingThe pattern does not match exactly (case, spaces)Check with grep first (grep -i ignores case), then add the I flag to sed: s/old/new/gI
Partial replacement (first occurrence only)Missing g flagUse s/old/new/g
sed: -e expression #1, char X: unknown option to 's'The text contains the / delimiterUse an alternative delimiter: s|old|new|g
File changed by mistake with -iNo prior backupRestore from .bak if sed -i.bak was used, otherwise from a system backup
Permission denied on a file in /etc/Insufficient permissionsUse sudo sed -i ...
Replacement in vim does not reach every lineLimited range (:s without %)Use :%s/old/new/g for the whole file
Special characters in the pattern (., *, [)Interpreted as regular expressionsEscape them with \: sed 's/192\.168\.1\.10/192.168.1.20/g'

Key points

  • sed -i 's/old/new/g' file is the most used replacement command in Linux administration.
  • Always check before using -i: run sed without -i or use grep -n to see the lines involved.
  • sed -i.bak automatically creates a backup copy: prefer it on critical files.
  • Nano (Ctrl+\) for one-off visual replacements.
  • Vim (:%s/.../gc) for replacements with line-by-line confirmation.
  • find + sed or grep -rlZ + xargs -0 sed for mass replacement across several files.
  • The dots (.) in IP addresses are regex special characters: escape them with \.

Knowledge check

Check that the essentials of this guide stuck. The questions cover only what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn