22 December 2023

How to use regex in vim to replace with an incrementing number variable

https://stackoverflow.com/questions/57756503/how-to-use-regex-in-vim-to-replace-with-an-incrementing-number-variable

I have a file which content like this:

id      phone   name
x'1234' 12345   jack
x'4567' 45678   Jojo
x'7890'  89456  Dio
x'4591'  34872  joseph

and i want to parse it into like this:

id  phone   name
1   12345   jack
2   45678   Jojo
3    89456  Dio
4    34872  joseph

I know basic regular expression could replace all id to any string like this:

:%s/x'\(\w\+\)'/1/g

and it will become:

id  phone   name
1   12345   jack
1   45678   Jojo
1    89456  Dio
1    34872  joseph

How to replace id to an increment variable ?

 ===================================

 

Mind that you can use an expression as the replacement string in the substitute command (:s). When the replacement string starts with \= it is evaluated as an expression.

Here, one possible solution is

:let i=1 | g/^x'\d\+'/s//\=i/ | let i=i+1

It finds all occurrences (one per line) of the ^x'\d\+' pattern and replaces it with the value if i that is incremented each time the match is found. As has been noted in comments, the | is a part of the g replacing "code", as "| is used to execute more than one command at a time".

Another solution is using the line() command (taking into account that your file has a header top line, so you should actually subtract 1 from the value returned with line()):

%s/^x'\d\+'/\=line('.')-1/

The ^x'\d\+' regex matches

  • ^ - start of a line
  • x' - x' string
  • \d\+ - 1+ digits
  • ' - a ' char.

There are other interesting "increment number in regex" examples at the Using an expression in substitute command page:

  • Number all the lines in a file (insert line number followed by a tab):
    :%s/^/\=line('.')."\t"/
  • Number a range of lines (from line 10 to line 20):
    :10,20s/^/\=line('.')."\t"/
  • Number a range of lines sequentially starting from 1:
    :let counter=0|10,20g//let counter=counter+1|s/^/\=counter."\t"
  • Number all the paragraphs in range starting from 1 (assuming the paragraphs are separated by one or more blank lines):
    :let counter=0|1,20g/^$\n^\s*[^\s]/let counter=counter+1|+1s/^/\=counter."\t"
    Note: The above command does not work for the first paragraph in the file if there is no blank line above it.

 

No comments:

Post a Comment