cybertextron
cybertextron

Reputation: 10981

copying just specific lines in a file with vim

Could someone please tell me know how to copy specific lines, for example Lines 10-20, 22, 24-30 in a file, so I can paste it to another file? I saw this stackoverflow post as someone had pointed out, however, I'm asking a different questionwhere

Upvotes: 3

Views: 4365

Answers (4)

lando2319
lando2319

Reputation: 1820

Here is a simple solution using Registers.

Using your scenario you provided, needing to yank Lines 10-20, 22, 24-30

Just yank each group with "A".

:10,20y A

:22y A

:24,30y A

At this point you have each of those sets of lines copied to your "A" register. Now you you can use p to paste as you normally would OR you can use "Ap (double quote, Letter of Register, then p to paste just those you yanked with to the A Register.

Read more about Registers Here and Here

Upvotes: 3

Conner
Conner

Reputation: 31090

Here's a fun little idea. Paste this in your ~/.vimrc:

command! -nargs=* Y :call YankList(<f-args>)
fun! YankList(...)
   let yanklist = []
   for i in a:000
      if match(i, "-") != -1
         let split = split(i, "-")
         let yanklist = yanklist + range(split[0], split[1])
      else
         let yanklist = yanklist + i
      endif
   endfor
   call setreg('"', "")
   for i in yanklist
      call setreg('"', getline(i), "al")
   endfor
endfun

Now you can specify lines to yank to the unnamed register. So do:

:Y 10-20 22 24-30

and use p to paste them wherever you want them. (inclusive)

I'd like to edit this post even though it's old to suggest the more "vimmy" way of doing this. See :help usr_10 | 131.

You could do:

10GV20G"ay
22G"AY
24GV30G"Ay
G"ap

Also, if there were some specific pattern that each of these lines contained, then you could grab them by said pattern. Say for example I wanted to yank all lines containing the word "foo", then I could do

:g/foo/y "

Upvotes: 4

sehe
sehe

Reputation: 393769

Use visual mode, or directly:

:10,20yank

Copy to a new file:

:new | put | 0d

Usually, you'll either have a criterion, e.g. move all lines containing pattern to the end:

:g/pattern/m$

To copy (:copy or :t)

:g/pattern/t$

To yank to a register:

:let @a="" | g/pattern/y A

Now, you can use it wherever you like e.g. "aP to paste it.

If you don't have patterns like that to use, just use text motions, e.g. }:y A to append a block of lines till the next empty line to register a etc.


Edit PS. I thought I'd explain a bit more why I mention m$ to move to the end (a personal favourite of mine):

If you opt to move/copy lines to the end of the file (m$), you can then write them to another file at once. E.g.

 :$mark a
 :g/pattern/t$
 :'a,$w newfile.txt

Copies the lines matching to file newfile.txt. Now delete the copy from the source file:

 :'a,$d

Upvotes: 3

Michael
Michael

Reputation: 1239

Have the both files open - invoke directly from the command line as vim fileone filetwo or open vim and then :e file. You can then switch between them with buffer commands, for two files :bn and :bp are equivalent (buffer next, previous). Then just copy the lines.

This can be done pretty easily: 10G to go to line 10, y10y to copy the next ten lines, then :bn and p to stick it in the other file.

Upvotes: 1

Related Questions