Kurt Keller's Blog

tech notes and more

add thousands of servers to a config file with just a few keystrokes

This post is a bit different from most other posts about vim in this space; it is longer and does not show one specific vim command, but instead describes how a few simple commands are strung together to shorten a very tedious and error prone task to just a couple of keystrokes.

Recently, at the office, we needed to add lines to a configuration file for a couple of thousand servers. The configuration file has a very strict format, forget a single comma or quote and the whole configuration becomes invalid; mix up the numbering of the servers and you are in trouble too.

Each server in the configuration file occupies one line:

␣␣␣␣␣␣␣␣"SRV000393":␣{␣"clientName":␣"pub_server"␣},

We needed to add this for all servers in the range SRV000000 to SRV000999, SRW000000 to SRW000999 and SRX000001 to SRX000010.

That’s 53 taps on the keyboard for each line (including the leading spaces and the carriage return at the end), 12 of them need the SHIFT key to be pressed simultaneously and 2 of them the AltGr key (at least on the keyboard layout I’m using). Multiply that with the 2020 lines we needed to add and you end up with over 100’000 keystrokes; a lot of typing practice and plenty of possibility for typos. Sure, by using autoindent mode you can save on the leading spaces, but still…

Type all that manually? No way! We’re smart, lazy and known for rarely making mistakes. So how you do this the easy, quick and safe way with vim (with only about 100 keystrokes)?

As always before you can automate something, you need to think the steps through. So let’s first outline what we need done and how we are going to do it:

For each server prefix do:

  1. Write the first line.
  2. Copy the first line.
  3. Increase the number in the server name by one.
  4. Repeat until you have all the servers.


Well, let’s get down to it.

Because the numbers of the servers have leading zeros and numbers with leading zeros are often interpreted as octal numbers (also by vim), we first need to tell vim to not treat numbers with leading zeros as octal:

:set nrformats-=octal

Now, place the cursor on the line just before where you want the first server line to be inserted and type

o

to open a new line below, then type the first line. Do this carefully, so you are sure there are no typos. With

<ESC>

you get out of insert mode. With

Ypp

you yank (Y) the current line and paste (p) it twice, so you end up with three identical lines.

Your cursor is now at the third line, which we make the template for the SRX servers:

3lrX<CTRL>-a

What are we doing here?

3l move the cursor 3 positions left so it is on the letter V
rX replace the character under the cursor with the letter X
<CTRL>-a increase the number under or right of the cursor by one

Now we go to make the second line the template for the second server prefix:

k6hrW

This means:

k move the cursor one line up
6h move the cursor 6 characters to the left, so it is on the letter V
rW replace the character under the cursor with the letter W

And finally move back to the first line with just one more keystroke:

k

Up to here, this has just been rather basic vi usage. We have three template lines and with them the fun begins:

qaYp<CTRL>-a<ESC>q

Wow, what was that?

Did you see the word recording in the status line? We have just recorded an on-the-fly macro:

qa start recording a macro into the macro name a
Yp yank the current line and paste it after the current line; this puts you at the start of the pasted line
<CTRL>-a increase the number under or right of the cursor by one
q end the recording of the macro

You probably already guess that we’re now going to run this macro 998 more times to get the remaining 998 lines for this server prefix. Repeating a macro is done by typing an at-mark (@), followed by the name of the macro (we used a here for the macro name). Of course we could type @a 998 times, but that would still be error prone and quite some finger acrobatics. Much better to just say “run the macro named ‘a’ 998 times”:

998@a

Voilà. Loooooooots of typing saved and no typos!

Do we need to record a new macro for the next server prefix? Nope, we don’t. The macro does not care about the prefix, it just copies the current line and increases the number it finds. So to insert the remaining 999 lines for the SRW server prefix we move one line down (j) and run the macro another 999 times:

j999@a

And finally for the server prefix SRX, we need to move one line down again and run the macro another 9 times:

j9@a

So now it’s time to save the new configuration, head for the cafeteria, take a break and when you come back you still can boast to your boss that you added all those 2020 lines to the configuration file already and were really careful not to make any typo while doing so.

Share

Leave a Reply