331

I am working with two files, and I need to copy a few lines from one file and paste into another file. I know how to copy (yy) and paste (p) in the same file. But that doesn't work for different files. How is this done?

Also, is there a way to cut-paste? I have tried googling, but most of the resources only talk about copy-paste.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
macha
  • 7,337
  • 19
  • 62
  • 84

19 Answers19

278

Since you already know how to cut/yank text, here are a few ideas for pasting it back into another file:

  • Edit the first file, yanking the text you want. Then open your second file from within vi (:e /path/to/other/file) and paste it
  • Open both files together in a split window and navigate between them using Ctrl + w, Up/Down either by:

    • vi -o /path/to/file1 /path/to/file2
    • From within the first file, Ctrl + w, s
Adam Batkin
  • 51,711
  • 9
  • 123
  • 115
  • 1
    I have two putty windows open, I am doing "v for visual mode first and then select all the lines and the do a "y" for yanking, not I am doing an alt+tab to get onto the other file and when I do a "p" for put, it only prints a quotation mark. – macha Jan 06 '11 at 22:42
  • 14
    If you are working with 2 putty windows, you have to use the putty/windows way of copy/pasting. That's easy. Mark the stuff you want to copy with your mouse (you don't have to do anything else, that marked text is now copied to the clipboard.) Switch to your other putty window. Enter insertion mode in vim(hit i). Hit the right mouse button - right mouse in a putty window will paste whatever is in the clipboard. – nos Jan 06 '11 at 22:46
  • 5
    What you are doing won't work: Yanking in vi won't place the text into your Windows clipboard, and the yank buffer isn't shared between open vim instances. – Adam Batkin Jan 06 '11 at 22:46
  • @macha: yeah it's a bit of a headbanger. I remember learning it after several years of using Visual Studio and it was pretty frustrating but now I use vim (not vi) daily. – sashang Jan 07 '11 at 00:44
  • 1
    I don't understand what the last point is supposed to do : * From within the first file, ```Ctrl``` + ```w```, ```s```. – svassr Mar 19 '13 at 15:16
  • @svassr It splits the window in half so you can open another file in the other buffer and them move between them, copying and pasting as needed – Adam Batkin Mar 19 '13 at 21:39
  • 1
    for me it splitted the window but opening the exact same file. How do you choose which file to open in then ? I have seen the command ```:sp myfile``` that split horizontally and open the specified file, but how would I do if I'd prefer to split the window vertically ? – svassr Mar 19 '13 at 22:34
  • `Ctrl` + `w`, `v` or `:vs`. If you have a split, you can open a different file using `:e filename` – Adam Batkin Mar 19 '13 at 23:40
  • I'm stuck on a keyboard without ">" so `cat` is out of question. This nifty trick just saved my day! – Jacksonkr Mar 25 '16 at 14:18
  • I've been unable to copy-paste from one file to another with vim for a few days now and couldn't find a solution even here. But for me the reason turned out to be simple: `~/.viminfo` file was read-only. Fixing file permissions helped. – Mikhail Antonov Apr 22 '17 at 21:36
  • Just to add `vim -p` as alternative to `vim -o` or `vim -O`. While the latter open the files in stacked mode (horizontal or stacked), the former use tabbed mode. You can navigate tabs using `gt` or `gT`. Also, they seems to be all options of `vim`, not `vi`. – tigerjack Apr 01 '19 at 14:32
  • I got confused (like the commentor above) about what exactly to do. For babies like me: (1) open one file in vim, (2) `ctrl+w`, then `s` to open a new split screen into the same file, (3) you can move up or down (between splits) via `ctrl-w`, then `up` or `down` arrow key, (4) use `:e fname.ext` to open your *other* file in one of the splits, (5) copy-paste by (a) use (3) to move to the right split, (b) use `yy` or something else to yank, (c) move to the other split with (3), and (d) use e.g. `p` to paste. Close the split by moving to it and using `:q`. – user3658307 Aug 16 '19 at 01:41
61

If you are using Vim on Windows, you can get access to the clipboard (MS copy/paste) using:

"*dd -- cut a line (or 3dd to cut three lines)

"*yy -- copy a line (or 3yy to copy three lines)

"*p -- paste line(s) on line after the cursor

"*P -- paste line(s) on line before the cursor

The lets you paste between separate Vim windows or between Vim and PC applications (Notepad, Microsoft Word, etc.).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JayG
  • 4,339
  • 3
  • 23
  • 19
  • 21
    Use `+` as cross-platform system clipboard register (Windows and Linux) vs. `*`, which is Windows only (`+` works just the same in Windows as `*`). – Stephen Swensen Oct 04 '13 at 17:11
  • As of 2021, in linux (pop_os 20.04), `*` works just as well as `+` for the applications mentioned in this answer, that is copy/paste between instances of vim and from vim to system application (vim 8.2, built with clipboard support) – calocedrus May 04 '21 at 07:11
53

Use the variations of d like dd to cut.

To write a range of lines to another file you can use:

:<n>,<m> w filename

Where <n> and <m> are numbers (or symbols) that designate a range of lines.

For using the desktop clipboard, take a look at the +g commands.

Apalala
  • 9,017
  • 3
  • 30
  • 48
  • To do this with marks, create two marks (a and b, for instance) around the text you'd like to write to a file: move to first line, `ma`, move to last line, `mb`. Then prepend a `'` to the mark's letter when you're using the above command: `:'a,'b w filename` – EchoLynx Apr 28 '17 at 19:29
  • great solution for wide-line ranges! – Yasin Okumuş Sep 18 '17 at 13:42
38

Here's one way to do it;

  • Start Vim and open file1 which is the file you're working on.
  • :e file2 which will bring up file2, the file you want to copy lines from.
  • locate the lines you want to copy. If it's three lines, you hit 3yy
  • :b1 this will switch to buffer 1, where file1 is
  • figure out where you want to insert the lines you yanked, and hit p

You could have both files viewable too. Split the screen with e.g. Ctrl + w s.

As for cutting, d cuts and places the cut stuff in the yank buffer. dd will "cut" a line.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
nos
  • 223,662
  • 58
  • 417
  • 506
  • 2
    off-topic: how do I get those keyboard-button-like things? – eckes Jan 06 '11 at 22:49
  • 1
    @eckes http://meta.stackexchange.com/questions/26207/how-can-i-format-as-keyboard-keys – nos Jan 07 '11 at 09:02
  • What about the two files are on two different ssh servers, which the same client ssh'es into in two different terminals in Linux/MacOS? I mean, no putty to use, and the two files can't be opened in the same vi session in one terminal. – Qiang Xu Mar 07 '18 at 23:24
  • 1
    If the client can ssh in to two servers, it can also use scp or sftp to those two servers. So the quickest way is to just copy the file from one server to the other so they reside on the same server, edit those files as described, and copy the file back to the other server when done if you need to. – nos Mar 08 '18 at 09:00
  • Resolved the issue I had. Thanks for the concise answer. – Tinashe Chinyanga Aug 25 '21 at 13:11
34

You can open the other file and type :r file_to_be_copied_from. Or you can buffer. Or go to the first file, go on the line you want to copy, type "qY, go to the file you want to paste and type "qP.

"buffer_name, copies to the buffer. Y is yank and P is put. Hope that helps!

geekosaur
  • 59,309
  • 11
  • 123
  • 114
Win Man
  • 929
  • 2
  • 15
  • 30
  • Working through ssh on local vi you still need to `:r scp:///` to read the file. Otherwise it will try to read the file from local storage. – mazunki Sep 28 '20 at 17:02
18

These are all great suggestions, but if you know location of text in another file use sed with ease. :r! sed -n '1,10 p' < input_file.txt This will insert 10 lines in an already open file at the current position of the cursor.

malik
  • 181
  • 1
  • 2
11

2017-05 update:

I just found that if you add the following line into your vimrc file,

set clipboard=unnamed

then Vim is using the system clipboard.


I just found the yank way won't work on the way where I copy contents between different Vim instance windows. (At least, it doesn't work based on my Vim knowledge. I don't know if there is another way to enable it to work).

The yank way only works on the way where multiple files are opened in the same window according to my test.

If you want to do that, you'd better use OS cut-copy-past way such as Ctrl + x, Ctrl + c (under Windows).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lichader
  • 340
  • 3
  • 13
8
  1. Make sure you have the Vim version compiled with clipboard support
    • :echo has('clipboard') should return 1
    • if it returns 0 (for example Mac OS X, at least v10.11 (El Capitan), v10.9 (Mavericks) and v10.8 (Mountain Lion) - comes with a Vim version lacking clipboard support), you have to install a Vim version with clipboard support, say via brew install vim (don't forget to relaunch your terminal(s) after the installation)
  2. Enter a visual mode (V - multiline, v - plain, or Ctrlv - block-visual)
  3. Select line(s) you wish to copy
  4. "*y - to copy selected
  5. "*p - to paste copied

P.S:

  • you can replace steps 2-5 with the instructions from the answer by JayG, if you need to copy and paste a single line
  • to ease selecting lines, you can add set mouse+=a to your .vimrc - it will allow you to select lines in Vim using the mouse, while not selecting extraneous elements (like line numbers, etc.) NOTICE: it will block the ability to copy mouse-selected text to the system clipboard from Vim.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
7

Goal: save a piece of one file to another file.

Solution:

  1. Select the text you want to save:
    • Position the cursor where you want to start selection
    • Press v to select characters OR uppercase V to select whole lines
    • Move the cursor to the end of what you want to select
  2. Save selected text to the new file. Type :wSpace and the name of the new file. Actually you'll see

    :'<,'>w new.txt

    Then press Enter

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ilya Serbis
  • 21,149
  • 6
  • 87
  • 74
7

These remaps work like a charm for me:

vmap <C-c> "*y     " Yank current selection into system clipboard
nmap <C-c> "*Y     " Yank current line into system clipboard (if nothing is selected)
nmap <C-v> "*p     " Paste from system clipboard

So, when I'm at visual mode, I select the lines I want and press Ctrl + c and then Ctrl + v to insert the text in the receiver file. You could use "*y as well, but I think this is hard to remember sometimes.

This is also useful to copy text from Vim to clipboard.

Source: Copy and paste between sessions using a temporary file

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
rovitulli
  • 319
  • 3
  • 8
7

While editing the file, make marks where you want the start and end to be using

ma - sets the a mark

mb - sets the b mark

Then, to copy that into another file, just use the w command:

:'a,'bw /name/of/output/file.txt
Sagar Jain
  • 7,475
  • 12
  • 47
  • 83
vman
  • 71
  • 1
  • 1
5

Copying text between two buffers (== files) that are opened in the same instance of Vim is no problem:

Simply yank in one buffer with y (assuming you marked a to-copy area in visual mode before), and then paste into the other buffer with p. It also works with different tabs as long as they're in the same instance of Vim.

How to open two files in the same instance of Vim depends on your system:

  • On Win32, there's an option in the context menu saying Edit with one vim if you select two or more files
  • When you're on the console, you can achieve it with vim file1 file2
  • If you use Vim as editor for another tool, be sure to specify the --remote-silent option to ensure that all files are getting opened in the same instance

If you opened the two files in two different instances of Vim, then you have to go with the system clipboard: in the first Vim instance, yank the text into the system clipboard using "+y (again, mark the area to be yanked in visual mode before), then go to the second Vim and paste the clipboard there: "+p.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
eckes
  • 64,417
  • 29
  • 168
  • 201
  • _:tabedit_ **filename** can be used to open target file and then just _p_ to paste your lines. I think it is quicker. – jabalv Jul 12 '17 at 12:28
3

My scenario was I need to copy n number of lines in middle, n unknown, from file 1 to file 2.

:'a,'bw /name/of/output/file.txt
Taryn
  • 242,637
  • 56
  • 362
  • 405
Shyam S
  • 31
  • 1
2

If you want to copy a part of a file and paste that content in the middle of another file, you can do this way.

:linenumber,linenumber write newfile

Example:

:2,34 write temp1

Or

:'mark, 'mark write newfile

Example:

:'a,'b write temp1

Now the lines are copied to another file. If you want to delete those lines after copying, you can do

:linenumber1,linenumber2 d

Or

:'mark1,'mark2 d

Now, go to other file. Then keep the cursor on the line where you wanted to paste.

Type

:r!cat temp1

Now, the content of the temp file is pasted here. You can delete the temp file from the command line itself, after pasting the content.

:!rm temp1

This would help if you wanted to copy and paste several times.

nobe4
  • 2,802
  • 3
  • 28
  • 54
SibiCoder
  • 1,396
  • 10
  • 21
1

Example: fileA and fileB - start in fileA at line 25, copy 50 lines, and paste to fileB

fileA

Goto 25th line

25G

copy 50 lines into buffer v

"v50yy

Goto fileB

:e fileB

Goto line 10

10G    

paste contents of buffer v
"vp
Kevin
  • 41,694
  • 12
  • 53
  • 70
Brenda
  • 11
  • 1
1

The below option works most of time and also for pasting later.

 "xnyy
x - buffer name
n - number of line to Yank - optional

The lines yanked will be stored in the buffer 'x'. It can be used anywhere in the edit.

To paste line(s) in the other file,

:e filename&location

Example: Type the below command in the current edit

:e /u/test/Test2.sh
and paste using "xP
P - before cursor
p - after cursor

Complete operation

open file 1 :

vi Test1.sh

a10yy

-Yanked 10 lines

-now open the second file from the current edit

*:e /u/test/Test2.sh*

-move the cursor to the line where you have to paste

*"ap*

--Lines from the buffer '*a*' will be copied after the current cursor pos

Ethaan
  • 11,291
  • 5
  • 35
  • 45
Raams
  • 167
  • 1
  • 7
  • Just for newbees like my self, you have to put " in front of what register you want to use: For yanking to x register: "xy and in new file to put it from the right register (x): "xp – mortenlund Aug 10 '22 at 10:42
0

Another way could be to open the two files in two split buffers and use the following "snippet" after visual selection of the lines of interest.

:vnoremap <F4> :y<CR><C-W>Wr<Esc>p
Thorsten
  • 1
  • 1
0

Enter command mode and run

:r! sed -n '<start_line_num>, <end_line_num> p' file_to_extract_text_from

E.g to extract lines 20-30 from filename into the currently opened file

:r! sed -n '20, 30p' filename
Anthony Awuley
  • 3,455
  • 30
  • 20
0

Set viminfo in your .vimrc:

set viminfo=%,<1000,'10,/50,:100,h,f0,n~/.viminfo

This will persist up to 1,000 lines of yanked stuff (your "registers") in the ~/.viminfo file when you quit Vim. It's restored when you start Vim, so you can paste it in a different file.

See the viminfo documentation for all the other stuff it can persist across sessions.

Daniel Darabos
  • 26,991
  • 10
  • 102
  • 114