How to split text into multiple lines based on a pattern using Vim?

20,427

To operate on the entire file, use this:

:%s/; /;\r/

To operate only on the selected text, use this:

:'<,'>s/; /\r/

English translation:

"Replace every occurrence of semi-colon followed by a space with semi-colon followed by a newline."

Explanation:

%    -    operate on the entire file
s    -    substitute
/    -    symbol that separates search/replace terms
;    -    the character you're searching for (notice I added a space)
;\r  -    the replacement text (semi-colon followed by newline)

That's about as basic as it gets for substitution in Vi.


For more geekiness:

I actually have the following mapped in my .vimrc file for situations like this:

"
" add a newline after each occurrence of the last search term
"
nnoremap SS :%s//&\r/<CR>

This command splits each line of a file at the first occurrence of the last search pattern.

So, for your use-case you would do this:

  1. search for ; (you may or may not want to include a space... up to you)
  2. type the following command in normal mode: SS

Each line of your file will get split at the first ; symbol.

To clarify, you would use the following 5 keystrokes:

/ ; ENTER S S

This is very handy for quickly formatting XML, HTML, etc...

Share:
20,427
Ori Popowski
Author by

Ori Popowski

Updated on October 14, 2020

Comments

  • Ori Popowski
    Ori Popowski over 3 years

    Suppose you have this text:

    name1 = "John"; age1 = 41;
    name2 = "Jane"; age2 = 32;
    name3 = "Mike"; age3 = 36;
    ...
    

    and you want to split each line into two lines to give a result like this:

    name1 = "John";
    age1 = 41;
    name2 = "Jane";
    age2 = 32;
    name3 = "Mike";
    age3 = 36;
    ...
    

    How would you automate this operation?

    Some notes:

    1. I already tried the following method:
      (1) Select the text in virtual-vode,
      (2) Execute :'<,'>:norm ^3f r^M ***,
      but it doesn't work correctly; it splits only half of the lines, because after every line is broken, the next repetition of the command applies to the rest of the broken line instead on the next line!
    2. This can be achieved using a macro but I'm looking for more elegant solution.


    *** explanation of the sequence:

    -norm for executing the following commands in normal-mode
    -^ for moving the cursor to the beginning of the line
    -3f<space> for moving the cursor to the 3rd space in the line
    -r^M for replacing that space with a new-line