2

Suppose I have a file and littered throughout are a bunch of placeholder strings for images, they all have img1.gif at present.

Is there a way to search for that string and increment the number each time, so the first result becomes img2.gif, the next img3.gif etc

I want to do this without plugins. I wondered if there is some way of accessing the search result number in a command? Thinking I can select the search result each time with gn perhaps?

4

You can do it in a single command line but it's a bit involved if you're not fairly well-versed in Vim. (You could also record a macro to do it but I prefer this approach.)

:let idx=0 | g/img1\.gif/ let idx += 1 | s//\='img' . idx . '.gif'/

We have two commands here, separated by |. The first, let idx=0 is simple enough: it just initializes a counter variable to 0.

The rest is all one g[lobal] command. This command searches for the pattern that is between the two / delimiters and for each match found the command or |-separated commands that follow it will be executed. In this case we have two such commands...

The first simply increments our counter.

The second is the well-known substitution command but with a couple twists.

  1. We don't specify a pattern. That means we reuse the pattern that follows g.
  2. The replacement part uses what's known as a sub-replace expression. This allows us to use a dynamic replacement that includes our incrementing counter.

A sub-replace expression is denoted by starting the replacement section with \=. Everything that follows that is evaluated as a Vim expression. The result of that evaluation becomes the replacement text. In this case our expression is the concatenation of two static strings and the counter variable: 'img' . idx . '.gif'. So if the counter is equal to 3 during an iteration the resulting replacement string is img3.gif.

If you'd like to learn more I have an answer that does a fairly deep dive into this useful feature.

2
  • Nice, thanks! The flexibility of Vim never fails to astound me, even if the ergonomics for mere mortals like myself are far tougher than something like Sublime's arithmetic features. The reality is I'll likely be back here every time I need to do this in future!
    – Ben Frain
    Aug 26 at 14:57
  • 1
    Heh. You're welcome. Yeah, Vim is mighty powerful...and challenging! Read that answer I linked. People have told me that it's pretty helpful for understanding those sub-replace expressions (which a lot of people are intimidated by or, at least, hesitant to tackle).
    – B Layer
    Aug 26 at 14:58

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.