ChatGPT解决这个技术问题 Extra ChatGPT

How do I yank all matching lines into one buffer?

vim

How do you yank all matching lines into a buffer?

Given a file like:

match 1
skip
skip
match 2
match 3
skip

I want to be able issue a command to yank all lines that match a pattern (/^match/ for this example) into a single buffer so that I can put it into another doc, or into a summary or whatever.

The command should wind up with this in a buffer:

match 1
match 2
match 3

My first thought was to try:

:g/^match/y

But I just get the last match. This makes sense, because the :g command is effectively repeating the y for each matching line.

Perhaps there is a way to append a yank to buffer, rather than overwriting it. I couldn't find it.

I have been doing this sort of thing all day and find the solution to be less that I would like. I do qaq followed by :g/pattern/normal "AY (didn't notice the :yank command before) then go to my buffer and paste it. Is there no straight forward way to redirect directly into a buffer? (Previously I'd been doing :redir @a :g/pattern/ :redir END, so this is certainly a step in the right direction, but I just want one. more. step...) :-) I suppose I could write a function easily enough...
I have both upvoted this question because it was useful to me and voted to close it because that's the only way I see to say "this should be on superuser.com". It's a great question, but I think that's the correct place for it. Sorry that a "close" vote is the only way to vote to move.
@NathanLong, I believe this question predates superuser. Probably should be migrated, though.

t
toraritte

:g/^match/yank A

This runs the global command to yank any line that matches ^match and put it in register a. Because a is uppercase, instead of just setting the register to the value, it will append to it. Since the global command run the command against all matching lines, as a result you will get all lines appended to each other.

What this means is that you probably want to reset the register to an empty string before starting: :let @a="" or qaq (i.e., recording an empty macro).

And naturally, you can use the same with any named register.

:help registers

:help quote_alpha

:help global

Using Vi/Vim: Ex and Ex-like Commands


What's implicit here is that one cannot append to the unnamed buffer, at least not in a single command. You may also need to clear the buffer first: :let @a=""
Just a tip if you optimize for key strokes. Clearing register can be done quicker, by recording empty macro qaq.
@J.A.Faucett unnamed register, not buffer. Also, you kind of can do it (based on this answer): :%g/regexp/let @"=@".getline('.'). It joins lines together, although there may be a way around that.
In case anyone is wondering - run :h multi-repeat to see docs for the :g command
J
Josh Lee
:help registers
:help quote_alpha

Specify a capital letter as the register name in order to append to it, like :yank A.


This tip alone doesn't answer the question. Instead of :g/^match/"Ay (as alluded to) you need to do .e.g :g/^match/normal "Ayy or :g/^match/yank A.
d
dash-tom-bang

Oh I just realized after commenting above that it's easy to yank matching lines into a temporary buffer...

:r !grep "pattern" file.txt

The simplest solutions come once you've given up on finding them. :)


:call setreg('a', system('grep "pattern" file.txt')) or simply :let @a=system('grep "pattern" file.txt') if you want it in a register.
A more general solution can use expand('%') for the current buffer's filename, e.g. :let @a=system('grep "pattern" '.expand('%'))