1

Let's say I have a file that contains a specific number that is always the same, something like the following:

1 1000
10 1000
100 1000
1000 1000
10000 1000
100000 1000
1000000 1000
10000000 1000
100000000 1000

I want to make this list like the following:

1 1000
10 1001
100 1002
1000 1003
10000 1004
100000 1005
1000000 1006
10000000 1007
100000000 1008

I'm struggling with a way of doing that. Only using a macro with Ctrl-A wouldn't be enough for generating this final result because I'd always have to press Ctrl-A once more when I go to the next line. Because of that, I thought I could use a command to act on every single line at once. I know the command :g/./norm $^A would generate the following list:

1 1001
10 1001
100 1001
1000 1001
10000 1001
100000 1001
1000000 1001
10000000 1001
100000000 1001

I also know that the command :echo line('$') gives me the number of the line that I'm currently editing. Is there any way of mixing these two commands? Something like :g/./norm $"echo line('$')"^A just so I can use the number of the line as a multiplier factor for the number of times that I need to press Ctrl-A?

That's the approach that I thought of when I tried to solve this problem... I'm not sure if this is the best suitable solution.


Edit:

I've also received suggestions on the comments for using g^A after selecting all lines... The problem with g^A is that it'll always edit the first appearance of the number on the line like the following:

1 1000
11 1000
102 1000
1003 1000
10004 1000
100005 1000
1000006 1000
10000007 1000
100000008 1000

The idea of selecting only the second column would be possible assuming that the columns are aligned. But for the files that I want to use this solution, I can't assume that they'll be aligned. Selecting everything and using 2g^A only increases the amount that is increased in each line like the following:

1 1000
12 1000
104 1000
1006 1000
10008 1000
100010 1000
1000012 1000
10000014 1000
100000016 1000

Is there any workaround for this? Perhaps having a way of selecting everything after the first space? In a way that I don't rely on using ^VG for selecting them because they're not aligned?

1
  • 5
    :help v_g_CTRL-A
    – Matt
    Mar 5 at 19:08
1
qa$<C-a>q
  • qa macro 'a'
  • $ go to end of line
  • <C-a> and increase
  • q quit macro
:g/0$/.,$ norm @a

works for me.

3
  • 2
    Cool... It works only using vim commands. Could you elaborate what .,$ means on :g/./.,$ norm @a? It works, but I didn't get what it's doing there.
    – raylight
    Mar 5 at 21:11
  • 2
    Welcome to Vi and Vim! Your answer is OK, but it's really hard to make sense of it... Can you please try to use code formatting for the Vim commands and perhaps bullets for the specific commands? Also, why not just use g/0$/norm @a to execute it on every line ending with 0? The .,$ makes it so that it matches the first one, then executes the macro on every line until the end of the file... That might be OK, but it's not very obvious...
    – filbranden
    Mar 5 at 22:48
  • 1
    This is basically :global/0$/.,$normal! $<C-a>
    – D. Ben Knoble
    Mar 6 at 14:01
2
:%!awk '{$2+=c++}1'

If no number in the column is zero, you can golf that to :%!awk '$2+=c++'.

$2 is the 2nd column. c is initially 0, c++ increments it. That 1 is equivalent {print}, so that you could also write a longer, equivalent version,

:%!awk '{$2=$2+c; c++; print}'

You can also refer to last column with $NF, the next to last with $(NF-1), etc. in case it's easier.

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.