Grepping with Vim
Of the many productivity-enhancing features that Vim has, one the the best for making similar changes to many files is grep, or vimgrep. This handy little tool will, from within vim, tell you how many files match your pattern, and then proceed to take you to each match, regardless of which file it occurs in. Sure, for straight /pattern/replacement/ text, there's nothing like sed -i, but if you've got to make changes which are similar or to similar areas but not the same, then vimgrep is your friend. To invoke this, you have two basic options. From the command line:
$> vim -c "grep <pattern> <files>"
or from within vim
:grep <pattern> <files>
This will invoke grep with standard external grep. If you wish to use vim's internal grep (mainly for systems without grep installed, it's slower but it does work), substitute "vimgrep" for "grep". First, vim will show you a list of matches for your pattern. Pressing <enter> will take you to the first match. From here, there are a few commands that will take you around to your different matches, and some flags you may want to have on to make your time easier. First, let's set the autowrite flag.
:set aw
or you can use the full, wordy version
:set autowrite
This will tell vim that when switching to the next/previous file in the match path, to automatically save your changes to this one. If you don't have this set, every time your next match is in a new file, you'll have to explicitly save the one you're in before the editor can take you to your next match.
Now for some basic moving-around commands. A quick primer on the sytax of these command definitions:
- items in [] are optional. Vim recognizes commands once enough of a unique pattern is entered to identify the command being called.
- In some cases, such as the above "aw/autowrite", there is an explicit alias also attached to the command.
- If you don't remember how to spell a command, enter the : followed by the first few letters of the command and then use the <tab> key to spin through the possible completions.
- the ! generally means to forget changes and switch to the next buffer/file/etc.
:[count]cn[next][!]- go to the next match. If [count] is specified, go to the [count]th next match.
:[count]cp[revious][!]- go to the previous match. If [count] is specified, go to the [count]th previous match.
:cl[ist]! [from] [, [to]]- display a numbered list of all matches
:cr[ewind][!] [nr]:cfir[st][!] [nr]- display match number [nr]. If this is omitted, go to the first match
:cla[st][!] [nr]- display match number [nr]. If this is omitted, go to the last match
:grepa[dd][!] [arguments]- same as grep, but instead of replacing the search results, add them to the existing results
:cope[n] [height]- open a window that shows the current error list, called a quickfix window. If [height] is given, make it that height, otherwise, make it 10 lines.
:ccl[ose]- close the quickfix window
The syntax for :grep and :vimgrep is slightly different, and the output as well. :grep will execute in a shell, and feed the results back into vim, thus you'll need to acknowledge this before vim will grab the results (hit enter after grep runs and displays its results). :vimgrep, on the other hand, puts the results right in vim and lands you at the first one without further ado. Both support recursive search, :grep through the standard method (grep -r), vimgrep through the "**" construct, as in
:vim[grep][!] /pattern/[g][j] **
Also, the optional [g] tells vimgrep to add every occurrence of a match to the list: without it, only the first match on a given line is added. The [j] option tells vimgrep NOT to jump to the first match, but just add the matches to the existing list. The [!] clears the existing list first.
The quickfix window is especially useful. This allows you to navigate through the files in non-linear order through a visual interface. In the quickfix window, each line is a match. When the cursor is on a line, ":.cc", "<enter>" or a double mouse-click will open the match in the window above.
Additionally useful is that vim actually saves the last ten lists of matches. To access these, use
:col[der] [count]- go to the previous list of matches. When [count] is given, skip back [count] lists
:cnew[er] [count]- go to the next list of matches. When [count] is given, skip forward [count] lists
One thing to remember, when you are at an older list (colder has been used) and you use :grep or :make to create a new list, it overwrites the next list. The easiest way to prevent this is to do ":cnewer 99" before using :grep again.
For more detailed instructions and command reference, visit the built-in help using vim by doing
:help grep
- Printer-friendly version
- Login or register to post comments
- 249 reads


