2

For example, to replace current line with all lines starting with '# ' , I use

:.! grep '^\# ' %

I know about the :g command that can filter lines to perform operations like

:g/call/d
:g/cat/ s/animal/mammal/g
:.,+20 g/^# / normal >>

But I am not able to figure out a way to just paste the filtered lines.

And how to use inbuilt help in this case?

:h :g gives an overview, how to find details on using commands like :g/call/d?

nobe4
  • 16,033
  • 4
  • 48
  • 81
Sundeep
  • 1,086
  • 7
  • 18

3 Answers3

3

Here is a way to do so, it gives nearly what you want, so you may be able to build your proper solution on that.

tl;dr

set a mark on the line to copy to with ma and run

:g/C/t'a-

decomposition

First of you can use the g command here, it filters lines matching a pattern. Then you can use the t command, which copy a line.

Let say you have the following file (A is just noise):

A
A
To replace
A
A
C 1
A
A
C 2
A
A

You can do

:g/C/t.

This will duplicate the lines matching C, because . reference the current line.

So if you want to duplicate the line at the current position, set a mark and use the command again:

ma
:g/C/t'a

You will have the following result:

A
A
To replace
C 2
C 1
A
A
C 1
A
A
C 2
A
A

Nearly there! You can add a - to the address of the paste to achieve the paste in the correct order:

:g/C/t'a-

Will produce:

A
A
C 1
C 2
To replace
A
A
C 1
A
A
C 2
A
A

Now you can delete the "To replace" line if you want.

Note: you can use the absolute line number instead of a mark if you want, i.e. :g/C/t12.

Regarding the help:

You already know about the :h :g that gives you the information that g takes an Ex command to perform action. So you might want to search for a command that copy.

:copy exists and can be abbreviated by :t. Both take an address to copy to.

:h {address} gives you want you need.

nobe4
  • 16,033
  • 4
  • 48
  • 81
  • 1
    thanks, lot of info here, will go through and ask further questions if needed – Sundeep May 13 '16 at 08:11
  • 2
    so, I tried these... ddma:g/^# /t'a- is the best fit I could do.. 'a- also gives the lines in same order as occurs in file, which I needed.. :h :t conveniently has help on :m as next item, so I now know how to move the filtered lines :) – Sundeep May 13 '16 at 09:38
  • 1
    Nice, let me add this to the answer! – nobe4 May 13 '16 at 09:42
2

There's copy, or t for short: :g/^#/t3 where 3 is the line you're currently on. You'd still need to delete the line itself afterwards (or before... when using dd before the global call, you can use :g/^#/t2 to exactly have your replace). Of course, you could also define a function and bind that to a key to have it all in one step, but imho that's overkill in this case.

Looking for docs, :h global will tell you about the usage of :g, which in turn refers to the [cmd] part. You can find the ex commands with :h ex-cmd. Also see http://vim.wikia.com/wiki/Power_of_g.

PhilippFrank
  • 1,225
  • 9
  • 13
1

You can redirect the ex command output to any register and then paste the register's content in a line.

   :redir @a
   :g/^#/p
   :redir END

Now, the lines starting with # are present in a register. You can go to that line and press dd and then paste it using "ap The content is pasted in the line. I have taken 'a' register.

SibiCoder
  • 3,372
  • 5
  • 20
  • 40
  • 1
    thanks for alternate solution, new command to learn.. I'll wait for any other answers.. plus this one requires lot of steps in which case I can as well stick to grep – Sundeep May 13 '16 at 07:26