Find and replace strings in vim on multiple lines
Categories:
Mastering Multi-Line Find and Replace in Vim
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.
/
if your search or replace string contains slashes. For example, :s#old_string#new_string#g
uses #
as a delimiter.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.
\n
in your search pattern, be mindful that it explicitly matches a newline. If you're trying to match a pattern that might span multiple lines but doesn't necessarily include a newline, you might need a different strategy, such as using \_s
for any whitespace including newlines, or performing multiple substitutions.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.