Showing posts with label regex. Show all posts
Showing posts with label regex. Show all posts

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.