Some More Vim Magic

Lets delay the next post about web scraping a bit longer to talk about vim again.

Imagine you have a file filled with thousands of sets of data, all of them looking like this one:

Some text here
more text
text text
ST 12345
more text
more text

The first line is the start of the set, and the last one is the end of the set. And then it is followed by another set. You will notice that one line in the set is a State, zip code combo. Imagine that you want to put the state and the zip code in their own line each. If you only had a few sets you may just do it manually, or create a macro. But if you have over 100K records, none of those options sounds good anymore. What you need is a global action (:g).

The idea is simple, find all the lines that follow the same pattern. The pattern being: Starts with 2 capital letters followed by a space, which is followed by 5 digits. The search pattern is easy:


/^[A-Z]\{2}\s\d\{5}

And performing a global action is also easy, for example, if you wanted to delete those lines you would do this:


:g/^[A-Z]\{2}\s\d\{5}/d

But we want to do something a bit more complex. We want to find the space in that match, and replace it with a <CR> (carriage return) so that we end up with State and Zip in their own line. My first attempt was this:


:g/^[A-Z]\{2}\s\d\{5}/normal ^f r<CR>

But that doesn’t work. You end up with lines looking like this:

CAR>

because we are searching for the space, replacing it with a < and then deleting from the space all the way to the end of the line, and entering insert mode. Then we insert “R>”.

What about this:


:g/^[A-Z]\{2}\s\d\{5}/normal ^f r\<CR>

It doesn’t work either.

I decided to take a look at the :normal help in vim. There I found out that if you want to use printable characters to represent non-printable one, you need to use :exec. So I came up with this one:


:g/^[A-Z]\{2}\s\d\{5}/exec "normal ^f r\<CR>"

That one worked.

Once more I got to experience the power of vim, and I have one more reason to not go back to my old editor. Since I went vim a couple of years ago, I’ve never looked back, and so far, I think I never will.