10

I've been receiving logged data in a text file that is just one long line with each value separated by a space. Is there a command or set of commands that will split one line into multiple lines?

18

You could simply replace any consecutive space on the line with a newline using the command :s/\s\+/\r/g. \s\+ mean one or more whitespace characters, and \r is a newline, see :help :substitute and :help regexp for details. If you run the command on a line like:

foo bar baz

You get:

foo
bar
baz

If you have hlsearch enabled and you don't want to clutter your screen with highlighted spaces everywhere, you can write a little function like the following to avoid it:

function! SplitLineNicely()
    " Save previous value of last search register
    let saved_last_search_pattern = @/

    " :substitute replaces the content of the search register with the `\s\+` 
    " pattern highlighting all whitespaces in the file
    substitute /\s\+/\r/g

    " Restore previous search register
    let @/ = saved_last_search_pattern
endfunction
  • "If you don't want to clutter your screen with highlighted spaces everywhere" this assumes too much about the OP's setup. – romainl Feb 13 '15 at 15:26
  • @romainl Better? – toro2k Feb 13 '15 at 15:28
  • 1
    Yes, it's better IMO. – romainl Feb 13 '15 at 15:42
  • 2
    It is \r, see :help s/\r. It could be replaced by a literal newline typing <c-v><cr>. In this context \n is a null character, see :help s/\n. – toro2k Feb 13 '15 at 16:09
  • 1
    replaces the content of the register - which register? – stillanoob May 1 at 11:49
5

Using vim's substitution is probably one of the better ways to accomplish your task, but you can use a macro as well. Suppose we have the following data, with the cursor somewhere on line 1:

1 a b c d e f
~

Starting in normal mode, hitting qq will start recording a macro callable via @q. Anything typed after qq will be repeatable via aforementioned call. Our goal is to record normal commands that will be general enough to allow for seamless repetition.

Thus, we may type 0 to bring the cursor to the start of the line, then fspace to move the cursor to the first space. This allows us to then type renter, resulting in:

1 a
2 b c d e f
~

Hitting q now is a good idea as our reusable macro is ready for repetition. Somewhat arbitrarily, we note that there are 4 spaces left to replace with newlines. Thus by hitting, 4@q, we repeat the q macro 4 times resulting in:

1 a
2 b
3 c
4 d
5 e
6 f
~

Note that because of the way we set up the macro, it would have been safe to repeat the command over 9000 times, as it would only affect the current line, and since there were no spaces to the right of the last data entry, fspace will 'nicely' fail, preventing data from being replaced with newlines.

So to repeat from the beginning:

qq0fspacerenterq9001@q

provides our result.

  • 1
    I love that you have a 9001 key on your keyboard for typing your username fast. – Rich May 2 at 12:24
2

The easiest way I've found to split lines in Vim is the normal mode command gq (type both letters in quick succession in normal or visual mode).

In visual mode, it will split whatever is selected, in normal mode, you follow gq with a motion.

For example, gql will split one line to the currently set width. To set the width of the split lines to be different from your current setting, you can use :set textwidth=n, where n is the number of characters you want in a line, e.g., 10 and change back to your normal width when you're done.

Got this information from a Youtube video by Kholidfu that shows how to join and split lines in normal mode using a motion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.