Find and replace strings in vim on multiple lines

Learn find and replace strings in vim on multiple lines with practical examples, diagrams, and best practices. Covers vim, vi development techniques with visual explanations.

Mastering Multi-Line Find and Replace in Vim

Vim editor interface showing multiple lines of code with highlighted search results

Learn powerful Vim commands and techniques to efficiently find and replace strings across multiple lines in your files, boosting your text editing productivity.

Vim is a highly efficient text editor, and one of its most powerful features is its ability to perform complex find and replace operations. While single-line replacements are straightforward, tackling multi-line replacements requires a deeper understanding of Vim's ex commands and regular expressions. This article will guide you through various methods to search and replace text across multiple lines, from basic global substitutions to more advanced techniques involving visual selections and ranges.

The Basics: Global Substitution with Ranges

The fundamental command for find and replace in Vim is :s (substitute). To apply this command across multiple lines, you need to specify a range. The most common range is %, which signifies the entire file. You can also specify line numbers or use visual selections.

:%s/old_string/new_string/g

Global substitution across the entire file

Let's break down this command:

  • :: Enters command-line mode.
  • %: Specifies the range as the entire file. You can also use line numbers like :1,10s for lines 1 to 10, or :'<,'>s for a visual selection.
  • s: The substitute command.
  • /old_string/: The pattern to search for. This can be a literal string or a regular expression.
  • /new_string/: The replacement string.
  • g: The 'global' flag, which means replace all occurrences on each line, not just the first one.

Using Regular Expressions for Flexible Matching

Vim's substitution command truly shines when combined with regular expressions. This allows you to match complex patterns, including multi-line patterns, and use captured groups in your replacement string. While Vim's regex engine is powerful, matching across line breaks requires special attention.

flowchart TD
    A[Start Substitution] --> B{Define Range?}
    B -- Yes --> C[Specify Line Numbers or Visual Selection]
    B -- No --> D[Use '%' for Entire File]
    C --> E[Enter Substitute Command ':s']
    D --> E
    E --> F{Define Search Pattern (Regex?)}
    F -- Yes --> G[Use Regex Metacharacters]
    F -- No --> H[Use Literal String]
    G --> I{Define Replacement String (Backreferences?)}
    H --> I
    I --> J[Add Flags (g, c, i, etc.)]
    J --> K[Execute Command]
    K --> L[End Substitution]

Vim Substitution Command Workflow

To match across multiple lines, you can use \_ before a character class or \n to explicitly match a newline character. However, a more common approach for multi-line patterns is to use a range that encompasses the lines you want to modify, and then use a regular expression that might span across those lines.

:%s/\(foo\)\n\(bar\)/\2\n\1/g

Swapping 'foo' and 'bar' if they appear on consecutive lines

In this example:

  • \(foo\): Matches 'foo' and captures it as group 1.
  • \n: Matches a newline character.
  • \(bar\): Matches 'bar' and captures it as group 2.
  • \2\n\1: Replaces with captured group 2, a newline, and then captured group 1, effectively swapping their order.

Interactive Replacement and Confirmation

For critical changes or when you're unsure about the regex, adding the c (confirm) flag is invaluable. This prompts you for confirmation before each replacement.

:%s/old_string/new_string/gc

Global substitution with confirmation

When prompted, you'll have several options:

  • y: Yes, replace this match.
  • n: No, skip this match.
  • a: All, replace this and all subsequent matches without asking.
  • q: Quit, stop the substitution.
  • l: Last, replace this match and then quit.
  • ^E / ^Y: Scroll screen up/down to see context.

1. Select the lines

Enter visual line mode by pressing Shift + V (uppercase V). Move your cursor up or down to select the desired lines. The selected lines will be highlighted.

2. Initiate substitution

Once lines are selected, press : to enter command-line mode. Vim will automatically pre-fill the command line with :'<,'>, indicating the range of your visual selection.

3. Enter the substitute command

After :'<,'>, type s/old_string/new_string/g (or gc for confirmation) and press Enter to execute the replacement only within the visually selected lines.