4

I have several lines that look like the following:

"Timestamp": 200,
"Timestamp": 1200,
"Timestamp": 3100,

I want to replace all the numbers, starting at 10 and incrementing by 10's so it looks like this:

"Timestamp": 10,
"Timestamp": 20,
"Timestamp": 30,
1

3 Answers 3

4

I am not sure if you are looking for pure :%s/// solution or not.

I would approach this with 10 + g + <C-a>:

  1. replace all numbers with 0: :%s/\d\+,/0,
  2. select all zeroes and increment them by 10: 10g<C-a>

enter image description here

3

You can use a Vimscript variable and increment it after each substitution. By using the :g command with a pattern, you can follow it with both a :s to replace the number (using \= in the replacement part to use the Vimscript variable) and also a :let command to increment the variable.

:let a = 10 | g/^"Timestamp": \zs\d\+\ze,$/ s//\=a/ | let a += 10

See:

  • :help :bar (the bar | is used as a command separator in Vimscript.)
  • :help :let to assign and increment a Vimscript variable.
  • :help :g (the :global command executes another Ex command for each matching line.)
  • :help /\zs and :help /\ze: these markers mark the start and end of the match in a regular expression.
  • :help :s for the substitute. The empty pattern // makes it reuse the same pattern from the :g command.
  • :help sub-replace-expression for using \= in a substitution replacement to evaluate a Vimscript expression.
2
  • How would you reverse this expression correctly? For example, what if the number was to the left of the colon, like 0 : "Timestamp" ? Would this work? :let a = 10 | g/ : \zs\d\+\ze,$/ s//\=a/ : "Timestamp" | let a += 10 Jun 1, 2023 at 19:12
  • 1
    @AdjunctProfessorFalcon You can use e.g. /\d\+\ze\s*: "Timestamp"/ as the pattern in that case, so g/\d\+\ze\s*: "Timestamp"/ s//\=a/ for the middle part of the expression. You don't need to change the :s command at all, only the pattern given to :g and make sure you still use \ze (and \zs if appropriate) to isolate the number you want to replace.
    – filbranden
    Jun 2, 2023 at 16:38
3

One more way, using a macro:

First set the unmamed register to contain zero:

:let @n=0

Then record into a register of your choice (but not the 'n' register, since we're using that above! e.g. qa to use the 'a' register) the following macro (where ^A is pressing 'ctrl'+'a'):

0Wdt,"nP10^A"nyiwj

The way it works is as follows:

  • 0W moves to the start of the line, then jumps to the number
  • dt, deletes the existing number
  • "nP pastes the contents of the 'n' register (which we initally set to zero)
  • 10^A increment the number we just pasted by 10
  • "nyiw replace the contents of the 'n' register by the incremented number
  • j move down to the next line

Now you can run apply the macro to all the remaining lines:

:2,$norm @a
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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