How to store grep results in a buffer in Vim?
Asked Answered
O

5

23

I want to debug a process, hence I attached strace to the process and redirected the output to a file and then performed the operation. During the process it has created a lot of processes. So here is what I want to do, I want to select all the system calls executed by a process. To do that I used grep command with pattern as pid:

:grep pid %

It shows the result but I am not able to traverse through the result, it promts

Press ENTER or type command to continue

and returns to the file. What I would like to do is store the result in a buffer and then have a look into it and if required save it into a file or else discard it and return to the original file. Is there a way to do this with out exiting from the vim editor? Thanks in advance.

I would like to search with the result and store that in a buffer.

Onanism answered 16/6, 2011 at 14:11 Comment(5)
Instead grep just use /pattern and then traverse it forward pressing N or backward pressing shift+NOpposition
Are you trying to view all of them from within vim? /pid should help you search. Or do you want all those lines into a file?Swaine
/pattern will be helpful to search within a code but here I want all the searched lines gathered in one place.Onanism
@Rahul: or use :g//p# to see grep like output for the whole bufferExpand
if you want to operate on all those lines: :g/pid/ normal >> will indent these lines, :v/pid/d deletes all other lines;Expand
E
20

You can go to older searches, and back easily:

:copen
:colder " goes to older
:cnewer " newer

You can have another search using lvimgrep (uses location window):

:lopen
:lnext
etc...

It also has history:

:lolder
:lnewer

You can read into any buffer:

:r!grep bla **/*.cs

Finally, any command that gives output, can be redirected with the redir command:

:redir >> file
:grep bla **/*.cs
:redir END

See :he redir for the many ways to use it (redirect into registers or variables).

Expand answered 16/6, 2011 at 15:1 Comment(5)
in case of lvimgrep, after one search and lopen, how do I search in this window?Onanism
in :r!grep bla */.cs can you explain it a bit more? what does grin means here?Onanism
@hue: sry my html emoticon was confusing there. I meant to /joke/ that obviously the usual commands apply. ':r!' Reads the console output of any (shell) commandExpand
At your first question: you can use % to represent the current filename; you used that in your own question so I assumed you knew what it meantExpand
one more thing: using redir you can set the output to a variable as well :help redir. ex: redir => m | silent registers | redir END then you can access that result at any time, ex: put=mArsenide
H
45

Over the years of reading all kind of logs, I learned this little trick:

:%!grep pattern

It simply replaces the current buffer contents with grep output (so to go back to the original logs you have to simply press u).

You can also use it with other tools:

:%!ack pattern
:%!ag pattern
:%!rg pattern

Note that you can also run these commands on other files then the current one. The following 2 commands would replace the current buffer with results of grepping over the current file (second % character, which would be redundant for grep in this case) and otherfile.txt respectively:

:%!grep pattern %
:%!grep pattern otherfile.txt

For me it's the simplest and the best solution for fast grepping of big files in Vim and I'm pretty surprised no one ever mentioned it.

Hubert answered 25/7, 2014 at 7:39 Comment(2)
Really wish I could upvote this more. I've been looking for this for years.Montalvo
To understand how the above commands work in vim: vi.stackexchange.com/a/5837Consistency
E
20

You can go to older searches, and back easily:

:copen
:colder " goes to older
:cnewer " newer

You can have another search using lvimgrep (uses location window):

:lopen
:lnext
etc...

It also has history:

:lolder
:lnewer

You can read into any buffer:

:r!grep bla **/*.cs

Finally, any command that gives output, can be redirected with the redir command:

:redir >> file
:grep bla **/*.cs
:redir END

See :he redir for the many ways to use it (redirect into registers or variables).

Expand answered 16/6, 2011 at 15:1 Comment(5)
in case of lvimgrep, after one search and lopen, how do I search in this window?Onanism
in :r!grep bla */.cs can you explain it a bit more? what does grin means here?Onanism
@hue: sry my html emoticon was confusing there. I meant to /joke/ that obviously the usual commands apply. ':r!' Reads the console output of any (shell) commandExpand
At your first question: you can use % to represent the current filename; you used that in your own question so I assumed you knew what it meantExpand
one more thing: using redir you can set the output to a variable as well :help redir. ex: redir => m | silent registers | redir END then you can access that result at any time, ex: put=mArsenide
D
3

I thought that :grep results were stored by default in the quickfix window.

Try to use :copen after running a grep command. I expect that you'll find your results there.

( :cclose to close the quickfix window)

It is not really a buffer, but as long as you are not starting another search your result list will stay intact.

You can "yank" the content of the quickfix window to a new buffer.

  • Go into quickfix with :copen
  • Yank its content with yG
  • open a new buffer with :new
  • Paste the content with p
  • Save it with :w Process1.txt

Repeat and rinse for multiple search/process.

Disprize answered 16/6, 2011 at 14:16 Comment(3)
xavier that was helpful. But yes I would like to start another search.Onanism
@Onanism : I have added some info on how to save your results. However, it might cumbersome to repeat on multiple process. The correct solution would be to do the same steps with a Vim script function but I am not proficient enough in Vimscript to provide a solution quickly but I am sure that someone else will.Disprize
Try looking at getqflist() and setqflist(). I know that they exist, though never used them actually.Crinite
P
1

@romainl 's answer on how grep results into separate buffer or split window gives a much cleaner answer than quickfix/location lists.

:vnew | 0r!grep foo #
:tabe | 0r!grep foo #

but Quickfix lists are sort of intended for what you are doing but not the way you are doing it; however, it's tedious to set up unless it's a recurrent task.

Probable answered 7/5, 2022 at 15:15 Comment(0)
C
0

If we want to store the line numbers of highlighted words along with their corresponding lines in gvim (similar to :g/), we can add the following code to ~/.gvimrc. Then, use :F to open the [Scratch] File.

command! -nargs=? F let @a='' | execute 'redir @a | silent g//print' | redir END | silent execute 'new | setlocal bt=nofile | put=split(@a, ''\n'') | set syntax=vera | 1d'

command! -nargs=? F: This defines a custom command named "F" that can take an optional argument (-nargs=? specifies that the command can take zero or more arguments).

  • let @a='': This clears the content of register "a". The register "@" is commonly used for yanking and pasting text in Vim.

  • execute 'redir @a | silent g//print': This part of the command executes the :global command (g//print) with the provided argument(s). The :global command is used to perform an operation on lines that match a given pattern. In this case, it's searching for lines that match the specified pattern (given by ) and printing them. The redir @a part redirects the output of the command to register "a".

  • redir END: This stops the redirection of output, ending the :redir command started previously. It ensures that subsequent output is not redirected.

  • silent execute 'new | setlocal bt=nofile | put=split(@a, ''\n'') | set syntax=vera | 1d': This executes a series of commands silently: new: This opens a new buffer.

  • setlocal bt=nofile: This sets the buffer type (bt) to "nofile", which means it's not associated with any file.

  • put=split(@a, '\n'): This splits the content of register "a" into lines and puts it into the buffer. The split() function is used to split a string into a list based on a delimiter ('\n' represents a newline character).

  • set syntax=vera: This sets the syntax highlighting of the buffer to "vera".

  • 1d: This deletes the first line of the buffer.

So, in summary, the command searches for lines matching a pattern, captures those lines, opens a new scratch buffer, populates it with the captured lines, sets the syntax highlighting, and then deletes the first line (which typically contains the pattern used for the search).

Chickweed answered 29/2 at 13:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.