5

I was looking for ways to search and replace on even/odd numbered lines in vim and I came across some solution on google groups https://groups.google.com/g/comp.editors/c/xk9DMoszgq4. To search and replace on odd numbered lines: :g/^/s/foo/bar/|+t+|-d

To search and replace on even numbered lines: :2,$g/^/s/foo/bar/g|+t+|-d

The solution works, but i couldnt understand on what it is doing. I know basics about using g to filter out lines for a pattern, then do search and replace on those lines. But I dont get it on what is the code post pipe | is doing.

Can anyone help me understand it ? Also point to some documentation if there is any, on what pipe does and how to use it ?

1 Answer 1

6

The global command marks every line matching a pattern and executes a list of actions on them. Each action is separated by the pipe symbol, |. In

:g/^/s/foo/bar/|+t+|-d

the pattern is ^, so all the lines are marked. Then, three actions are executed on the marked lines:

  1. s/foo/bar/: substitute "foo" by "bar".
  2. +t+: Duplicate the next line. Note that the duplicate, which becomes the current line, is not marked.
  3. -d: Delete the previous line, which had been marked by the global command and is a duplicate of the current line.

As you can see, while the global command marks all the lines, the net effect of steps 2 and 3 is to clear the mark of even lines.

For documentation see :h :g, :h :t, :h :d and :h :bar.

Note that operation is more efficiently done with Sed, which you can invoke directly from Vim, for even and odd lines respectively:

:%!sed 'n;s/foo/bar/'
:%!sed 's/foo/bar/;n'
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.