Vim: insert text using regex

I have several lines that I convert from excel to wiki and want to add link tags for a piece of text in each line if there is text in this field. I started the conversion work and came to this question:

|10.20.30.9||x|-|| |10.20.30.10||x|s04|Server 4| |10.20.30.11||x|s05|Server 5| |10.20.30.12||||| |10.20.30.13||||| 

I want to change the fourth column, for example. "s04" - "[[server: s04]]". I do not want to add parentheses for links if the line is empty, or if it contains a "-". If "-" is a big problem, I can remove it.

All my regular expression attempts to get something from a string end in the entire replaced string.

+4
source share
7 answers

Let me recommend the following substitution command.

 :%s/^|\%([^|]*|\)\{3}\zs[^|-]\+\ze|/[[server:&]]/ 
+1
source

Use awk to do this:

 #!/bin/bash awk -F'|' ' { OFS = "|"; if ($5 != "" && $5 != "-") $5 = "server:" $5; print $0 }' 

NOTE. I edited this script from the first version. This current, IMO is better.

Then you can process it with:

 cat $FILENAME | sh $AWK_SCRIPTNAME 

Switch -F'|' tells awk use | as a field separator. The if/else and printf if/else pretty straightforward. It prints the fields, and "server:" is added to column 5 only if it is not a "-" or "" .

Why is column 5, not column 4 ?: Because you use | at the beginning of each entry. So awk takes the “first” field ( $1 ) as an empty string, which, in her opinion, should have happened before this first | .

+4
source

This is similar to working on the sample you pass there (with Vim):

 %s/^|\%([^|]*|\)\{3}\zs[^|]*/\=(empty(submatch(0)) || submatch(0) == '-') ? submatch(0) : '[[server:'.submatch(0).']]'/ 
+4
source

It is probably best to use awk, as ArjunShankar writes, but this should work if you remove the "-";) It didn’t work for him to work there.

 :%s/^\([^|]*|\)\([^|]*|\)\([^|]*|\)\([^|]*|\)\([^|]\+|\)/\1\2\3\4[[server:\5]]/ 

This is just stupid. The first 4 are identical (correspond to all up to 4 times). Failed to work with {4}. The fifth corresponds to the lines s04 / s05 (it simply requires that it not be empty, so the "-" must be deleted).

+3
source

Adding a bit more readability to ideas given by others:

 :%s/\v^%(\|.{-}){3}\|\zs(\w+)/[[server:\1]]/ 

The task is completed.

Notice how {3} indicates the number of skipped columns. Also note the use of \v for the very magical regex mode. This reduces the complexity of your regular expression, especially when it uses more "special" characters than literal text.

+2
source

to try

  :1,$s/|\(s[0-9]\+\)|/|[[server:\1]]|/ 

assuming your s04, s05 are always s and a number

0
source

A simpler replacement can be achieved with this:

 %s/^|.\{-}|.\{-}|.\{-}|\zs\(\w\{1,}\)\ze|/[[server:\1]]/ ^^^^^^^^^^^^^^^^^^^^ -> Match the first 3 groups (empty or not); ^^^ -> Marks the "start of match"; ^^^^^^^^^^^ -> Match only if the 4th line contains letters numbers and `_` ([0-9A-Za-z_]); ^^^ -> Marks the "end of match"; 

If the _ character is like - , can be displayed, but cannot be replaced, use the following regular expression: %s/^|.\{-}|.\{-}|.\{-}|\zs\([0-9a-zA-Z]\{1,}\)\ze|/[[server:\1]]/

0
source

Source: https://habr.com/ru/post/1413771/


All Articles