Thirty Minute Solution with Vim

Today on IRC a friend had an issue he was trying to solve using Vim. He had a sed/awk solution but was interested in seeing if it could be solved in Vim.

The problem was a common one, one that I’ve run into before. I’ve got this giant list of data but all of the primary key’s are ‘1’. How do I automate the process of incrementing the primary key?

Here’s a sample of the data:

[
  {
    "pk": 1,
    "model": "app.model",
    "fields": {
      ..
    }
  },
  {
    "pk": 1,
    "model": "app.model",
    "fields": {
      ..
    }
  },
  {
    "pk": 1,
    "model": "app.model",
    "fields": {
      ..
    }
  },
  ...
]

You can see there that all the “pk” lines contain a ‘1’.

So how do we do this in Vim?

First we looked at how to match the “pk” on each line, which can be done by this search parameter in Vim:

:g/pk/

Then we needed to get to the digit, so we added:

:g/pk/s/\d\+

The \d+ finds the digits on that line (the ‘+’ just matches more than one digit). We are putting this in a s/ since we eventually want to search and replace the ‘1’ with an incremented number.

So far we are on the proper line, we’ve matched the digits on that line, how do we increment them?

We need to start at one (at the top of the file) so lets add to our line above:

:let i=1|1,$g/pk/s/\d\+/

Here we’ve set the variable “i” to 1. We’ve also stated in “1,$” that we want to match the entire file. This can actually be shortened to “%”.

Now we need to change \d+ to “i”, and then increment “i”.

:let i=1|%g/pk/s/\d\+/\=i/g|let i=i+1

Huh? Lets take a look at what we’ve added.

  • We shortened our ‘whole’ file setup to ‘%’
  • We’ve added the replacement value ‘\=i’
  • We want to match the entire file ‘/g’
  • And finally we increment “i” with ‘let i=i+1’

Lets run that on our example data and see what we get?

[
  {
    "pk": 1,
    "model": "app.model",
    "fields": {
      ..
    }
  },
  {
    "pk": 2,
    "model": "app.model",
    "fields": {
      ..
    }
  },
  {
    "pk": 3,
    "model": "app.model",
    "fields": {
      ..
    }
  },
  ...
]

Bingo!

  • 8 months ago
  • Permalink
  • Share
    Tweet
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.