I want to create a 'quickfix' list (see :help quickfix
) with all files that contain lines with "abc" but not "xyz". I was hoping I could run the following vim ex command:
:grep -nHr abc * | grep -v xyz
Unfortunately, vim doesn't like the "pipe" and the command fails. What is the best way to do this from within vim?
grep is very often used as a "filter" with other commands. It allows you to filter out useless information from the output of commands. To use grep as a filter, you must pipe the output of the command through grep . The symbol for pipe is " | ".
If you want the output to go into a file, use grep ... > /tmp/foo . You can add && vi /tmp/foo on the end if you want to edit that file immediately. In fact there's no such thing as a "vi file". vi operates on arbitrary text files; the files themselves are not directly associated with vi .
External grep is nothing but Vim invoking the commandline grep in a shell child process. This is super dumb: Vim just invokes whatever you pass it verbatim and grabs the grep output, parses it and fills it in the Quickfix window. To search in all files in the PWD: :grep Xanadu *
Basically vim provides these commands for searching files: The articles feature more information regarding their usage. This will put in the vim command line a list of all the files that match the regex. The "+/..." option will tell vim to search from the start of each file until it finds the first line that matches the regex.
Running vi or vim with '-' as an argument makes it read the file to edit from standard input. Hence: will do what you need. Show activity on this post. Apart of vim -, you can also use process substitution using the < (command) syntax, in example:
You can check what is the PWD using the command :pwd. So, it is to your advantage to invoke Vim from the base directory of a code base. This is the grep feature that is implemented inside Vim. Not surprisingly, this internal grep is far easier to use compared to Unix grep.
For some reason I can't leave this one alone!
How about use :!grep ... > filename
followed by :cf filename
, which will open the output as a quickfix list.
It's many years later, but I found more direct alternative. cexpr
command in vim. It pretty much implements the answers from @jwd and @skeept, and is a bit more flexible because it accepts a list.
Below is an example use of my own which uses pipes. I prefix all my questions in my work notes with Q:
to find them quickly. I wanted to use quickfix list and vim to browse through questions, viewing the most recent first.
:cexpr system("grep -R --line-number Q: --exclude '*~' ~/_Notes/work-log/ \| sort \| tac")
Relevant excerpt from the vim help.
:cex[pr][!] {expr} Create a quickfix list using the result of {expr} and
jump to the first error.
If {expr} is a String, then each new-line terminated
line in the String is processed using the global value
of 'errorformat' and the result is added to the
quickfix list.
If {expr} is a List, then each String item in the list
is processed and added to the quickfix list. Non
String items in the List are ignored.
See |:cc| for [!].
Examples: >
:cexpr system('grep -n xyz *')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With