# Continuous number substitution

Suppose you have a textfile:

``````Time step #1 (t = 0 a.u. = 0 fs)
unneccessary text unneccessary text unneccessary text
...
Time step #2 (t = 10 a.u. = 0.24189 fs)
...
Time step #3 (t = 20 a.u. = 0.48378 fs)

Time step #1 (t = 0 a.u. = 0.0 fs)
...
Time step #2 (t = 10 a.u. = 0.24189 fs)
...
``````

How can I use regular expressions in order to make the time steps continuous in the form:

``````Time step #1 (t = 0 a.u. = 0 fs)
unneccessary text unneccessary text unneccessary text
...
Time step #2 (t = 10 a.u. = 0.24189 fs)
...
Time step #3 (t = 20 a.u. = 0.48378 fs)

Time step #4 (t = 30 a.u. = 0.72567 fs)
...
Time step #5 (t = 40 a.u. = 0.96756 fs)
...
``````

Generalized my question could be rephrased as:

How can a certain pattern be matched multiple times and the pattern

``````TIME STEP #N (t = N * 10 a.u. = N * 0.24189)  with n in range(0,5002)
``````

be substituted?

• Welcome to Vi and Vim! Can you describe how you want the values in parens to be adjusted? I have a solution (an idiom, really) for the first part, but the second part is unclear. Please edit to add more details. – D. Ben Knoble May 27 at 15:53
• In the end, I would like to end up with: TIME STEP #1 (t = 0 a.u. = 0 fs) TIME STEP #2 (t= 10 a.u. = 0.24 fs) TIME STEP #3 (t = 20a.u. = 0.48 fs) and so on – Lamba May 27 at 15:54
• To clarify, the pattern is time step `t` means `10*t a.u.` and `0.24*t fs`? – D. Ben Knoble May 27 at 15:57
• in an abstract way: TIME STEP #N (t = 10*N a.u. = 0.24*N fs), if you mean that, yes. – Lamba May 27 at 16:00

There is an idiom (one example) of using an incrementing counter in `:global` commands combined with `:s/.../\=` commands. In virtually all cases, you'll start with

``````let counter = 0
``````

Though you may use another number if you need to start counting from, e.g., one.

The next step is to invoke a command on the lines you care about, which generally involves

``````global/pattern/command | let counter += 1
``````

Because the increment happens for each line, we can use `counter` to build sequences. Additionally, if `command` is a `:substitute` with the same pattern, we can use `//` for a shorthand.

To get expressions into a replacement, which allows us to compute arbitrary replacement strings, we use `\=`. I generally use a form like `printf()` to build the target string because I find it easier to read than string concatenation.

In the end, the full commands are

``````let counter = 0
global/Time step #\zs\d\+ ([^)]*)/substitute//\=printf('%d (t = %d a.u. = %f fs)', counter, 10*counter, 0.24*counter)/ | let counter += 1
``````

Running this on your test case, I get

``````Time step #0 (t = 0 a.u. = 0.000000 fs)
unneccessary text unneccessary text unneccessary text
...
Time step #1 (t = 10 a.u. = 0.240000 fs)
...
Time step #2 (t = 20 a.u. = 0.480000 fs)

Then a lot of text and after a while again

Time step #3 (t = 30 a.u. = 0.720000 fs)
``````

You may want to adjust the precision on `%f` (something like `%.2f` or `%.3f`, depending on how many entries you have); the default is 6.

• That was really helpful! Thank you also for the thorough explanation! – Lamba May 27 at 18:05
• @Lamba you're welcome! General practice is to wait 24 hours or so before accepting an answer, but accepting an answer is a way to say "this solved my problem." Just so you know! Accepting answers – D. Ben Knoble May 27 at 18:27