vim I use
p all the time to yank and paste lines. However, if I want to replace one line multiple places in the file, I can't use
p because the
dd deletes the line to the clipboard / register. While I should probably know how to use registers better, i feel like there is probably a way to
p that replaces the current line.
By default, the paste commands use the
" (“unnamed”) register. Effectively, any command that writes to a register also writes to the unnamed register, so yanks, deletes, and changes all affect it. This is why your yank-delete-paste sequence pastes the deleted text instead of the yanked text.
0 register can help here. Any yank commands that do not specify a register put the yanked text in register
0 (in addition to
"). It is not affected by delete or change operations, so you can use it to paste a yanked line multiple times even if you do intermediate deletes or changes.
"both now have the yanked line.
- Move to a line to replace.
"now has the deleted line, but register
0still has the yanked line.
"0P: Paste the originally yanked line from register
- Move to the next line to replace.
dd"0P(same as above)
(Due to the way cursor positioning works when replacing the last line of a buffer, you will want to use
"0p instead of
This is very close to Bruce Ediger’s answer, except that you do not have to specify a register when initially yanking. Using one or more named registers can be very handy though if you need to (for example) replace some lines with
AAA, but other lines with
AAA in register
BBB in register
b (or leave one of them in register
0), then paste them accordingly).
You can also paste from
0 in line-wise visual mode (
V) to save a keystroke:
If you do not like having to type
"0, you might find a mapping more convenient:
noremap <Leader>p "0p noremap <Leader>P "0P vnoremap <Leader>p "0p
An alternate approach is to delete to the
_ (“blackhole”) register. When you delete to it, the
" register is not affected, so your yank-delete-paste sequence can still paste the yanked text from the unnamed register.
"both now have the yanked line.
"_dd: No change to the registers.
P: Paste the originally yanked text from register
Again, you might find a mapping more convenient:
noremap <Leader>d "_d
Looks like Kevin has a pretty good answer, but if you want to lay eyes on each line you delete, then replace, a slightly different solution exists.
1. Find line to copy in some select number of places. 2. Put cursor on it. 3. "ayy copies that line into register 'a'. 4. Find line to replace. Put cursor on it. 5. dd deletes that line. "aP inserts the copied line above where the cursor now lies. 6. Repeat steps 4 and 5.
This sort of recipe allows you to use pattern matching to find lines to delete and replace, and you can go back to the start of the file (1G) and search forward as often as you like. If I have 2 or more lines to gather and place repeatedly, I use
"ayy for the first line,
"byy for the second,
"cyy for the third, and so forth. I made a habit (which reduces the generality of the recipe) to decrease the mental load on me.
There are a couple ways to do this with
:s, depending on how much typing you want to do. The easiest way is a simple search and replace:
:%s/find this line/replace with this/
% will search the whole file and replace all occurrences.
If that's too much typing for you, you can yank the destination string (
yy) and use the
" (default) register, inserting it with Ctrl+r ":
Or, if you have a copy of the replacement string, you can yank the two into separate registers with
"byy to yank into the
b registers, respectively (you can use any letter for your registers). Then use Ctrl+r a and Ctrl+r b to paste them into the search and replace fields.
Not to one-up Bruce, but if you want to check lines before you replace them, just add the
:%s/find this line/replace with this/c
I use the
c, "change", command quite frequently for this kind of thing, combined with regular search. You can search the file for each line/piece of text you are interested in and then use consecutive
n. commands (
n for next and then
. to repeat the last change.)
/^hello - find line beginning with hello;
c$goodbye - change line to goodbye;
n. - repeat find, repeat change
If you want to change the line to one already in the file, you could just copy it into your input buffer (assuming your GUI permits it) and then paste to get the content of the first change command.
As with all things vi, it is a good idea to have a lot of options in your pocket, depending on what kind of edit you want to do.
V p yy
V to select line,
p to paste, then
yy to re-yank the line you want to re-paste, since
V p overwrote the clipboard.
This is a corrected version of this answer.