views:

172

answers:

3

Assuming the following text file, which is actually a data dump of funds and price statistics:

PBCPDF
05/01/2006
 0.0000
 0.0000
PBCPDF
 0.0000
06/01/2006
 0.0000
 0.0000
PBCPDF
 0.0082
[… lines repeat …]

What I wanted to achieve is to delete all instances of PBCPDF except for the first one, which I could write the substitution command as :.+1,$s/PBCPDF\n//g.

However, since I wanted to program a macro to process multiple fund names, I need a means to use some sort of pattern that would retrieve the current line as the search pattern without me doing it by hand.

Is there a way to do that?

A: 

If you're doing this in a macro (using the q command) it's smart enough to catch when you do some of the more esoteric keystroke commands - the one I'm specifically thinking about is CTRL-R, CTRL-W, which will insert the word under the cursor into the command line. So, for example, if you did

ESC
qw
/[CTRL-R, CTRL-W] (you should see the word under the cursor enter the command line)
[enter]
q

then you just created a macro that searches for the next word in the buffer that's the same as this one, get it? It will dynamically yank the word under the cursor into the command as part of the macro. There might be something like CTRL-W in the command above that does this for the whole line, but I don't know it offhand.

Matt
+4  A: 
ggyy:+1,$s/<Ctrl-R>"<BS>//g

Let's see what that does, exactly.

Go to the first line

gg

Yank the entire liine

yy

Start the substitution

:+1,$s/

Get the current line from the register to which you yanked it to:

<Ctrl-R>"

Note: Don't type the ", you have to actually hold Control and press R, followed by a double quote.

Delete the end of line character:

<BS>

Note: press Backspace.

Replace with nothing.

//g

You can record this in a macro by wrapping it with a qq/q, or whatever.

sykora
Great explanation!
Seh Hui 'Felix' Leong
A: 

Having studied sykora's and Matt's answers, I came up with a slightly better improvement which works on a line-wise basis rather than a word-wise basis (as per Matt's solution).

This command is to be executed after the cursor is positioned on the line of which the deletion is to occur:

:.+1,$s/<CTRL-R>=getline(".")<CR>\n//g

Explanation for VIM beginners:

:.+1,$s/

Start substitution from the line after the current line (.+1) and the end-of-file ($)

<CTRL-R>=getline(".")<CR>\n

<CTRL-R> refers to the actual pressing of the CTRL and R keys, which allows you to enter special expressions. In this case, =getline(".") which retrieves the text of the current line.

<CR> refers to the pressing of the enter key, which completes the <CTRL-R> expression. I also specify the newline character (\n) at the end of the search pattern as I need to remove it.

//g

And then replace with nothing.

Seh Hui 'Felix' Leong