Using Vi/Vim: Ex and Ex-like Commands

In This Section

The Ex, or colon, commands are based on the line editor named ex. In general, they operate on the document as a whole, or large portions of it (although there are commands to perform essentially every editing task). Of course, you already know about two of these commands, :w and :q, to save a file and to quit, respectively.

We may break down the most common Ex commands into two categories: commands that affect the editor (such as saving files or quitting) and commands which process or filter the text of a document in some way (such as replacing a word with another).

Text Processing Commands

The text processing commands generally have a syntax like:

: [ range ] command [ args ... ]
The range specifies a number of lines on which the command will act. A single number represents just that line; two numbers separated by a comma indicate a range of lines. Special symbols which may be used as line numbers include:
. (dot)
The current line
$ (dollar)
The last line of the document
% (percent sign)
All lines; equivalent to 1,$
You may also add and subtract numbers, so $-5 would represent the fifth line from the bottom, and +3 indicates three lines below the current line (the dot is implied if nothing is specified).

The :p command makes a good example command for ranges, as it simply prints out everything within the range. Here are some sample commands to try:

If no range is specified, the range used will depend on the specifics of the individual command, but it will generally be just the current line. Some commands, however, have different meanings when used with no range.

Although there are many Ex text-filtering commands available, I generally find three commands to be the most useful. They are described below.

Search and Replace

The :s command performs a search and replace operation. It has the following syntax:

:[range]s/pattern/replacement[/flags...]
Without the range, it acts only on the current line.

What this command essentially does is search for the pattern on each line, and, if found, replace the matching portion with the replacement text. For example, the command

:%s/hello/world/
would replace the word "hello" with the word "world". The slash at the end is optional. To put a literal slash in the pattern or replacement text, you can put a backslash before it:
:%s/hello/\/world\// replaces "hello" with "/world/"
or, you can use a different character as the delimiter:
:%s#hello#/world/# does the same thing
In the replacement string, you can use the & symbol to put in the matched search string. So if you are on a line reading
hello you wonderful world!
and you enter the command
:s/hello.*world/***&***/
you would get
***hello you wonderful world***!

Additionally, you may group parts of your pattern using \( and \), and then reference them by \1, \2, and so on, the number referring to which part of the pattern you have delimited. This is especially powerful if you have a database-like or table-like file, such as one with tab-delimited or colon-delimited fields. So say you have a file which reads:

Last:First:Age
Smith:John:17
Doe:Jane:23
...
You could then run the command:
:2,$s/^\(.*\):\(.*\):\(.*\)$/\2 \1 is \3 years old./
and you would get a nice report. Be careful, though, since \(.*\) will match as much as possible, so if you had more fields, you might be in trouble. Instead, you could use something like \([^:]*\).

Finally, a number of flags may be appended to the end of the search. The most common of these are i and g. The i flag makes the search case-insensitive. The g flag means "replace as many times as possible within the line." You may have noticed that, within any line, only one substitution is performed normally. With the g flag, the substitution will be performed as many times as possible. So on a line reading abcabcabc, the command :s/c/z/g would result in abzabzabz; without the g you would get abzabcabc. Of course, when there are flags present, the extra third delimiter is no longer optional.

Global Actions

There are a lot of Ex commands, such as :d. which perform really simple operations like delete lines. Naturally, this is no more efficient than, say, the dd operation. But say you wanted to delete all lines matching some pattern (e.g., all blank lines). This is what the :g command is used for. Its syntax is:

:[range]g/pattern/command
The default range is the entire document (%). Essentially what this does is search for all lines matching the given pattern and perform the command on them. So the solution to the above problem would be the command :g/^$/d, which would find all lines with nothing between their start and end and delete them.

Interesting trivia note: Since the pattern is a regular expression, it is sometimes referred to by the abbreviation "re". Before there were visual editors like Vi, it was often useful to print out all the lines matching some pattern, using the :p command. So people would enter commands of the form:

:g/re/p
which is where the grep command got its name.

All-Purpose Filter

The substitution and global commands are enough to do most text filtering, but sometimes other programs could do the job better. Say, for instance, you wanted to sort several lines of your document. The :! command can be used to filter a part of your text through any Unix command. It has the syntax:

:range!command
Without the range, you just get to see the output of the command, but it doesn't actually change your text, which isn't all that useful (although if you just want a quick ls or something, it's nice). For the example above, you could use :3,8!sort to sort the lines. The part of the document given in the range is provided to the program's standard input; it is replaced by the program's standard output. If you want the output of a command which takes no input, try creating a line (with the o or O command) and then running :.!ls or whatever command you want.

As a side note, there's also a command :r which takes a filename as its argument, and basically "reads" the file into your current document. Just so you don't try something weird like :.!cat file...

Editor Commands

You've already learned the two most important editor-related Ex commands, :w and :q. There is a third command, :e, which means "edit file," and takes as its argument a file name; this allows you to edit another file.

All three of these commands can take an exclamation mark immediately after the command letter (e.g., :q!). The exclamation mark means "force the action," and is used to override an error in performing the normal action. The :w! command will write the file even if it is readonly (unless, of course, you really don't have permission to the file), the :q! command will quit without saving, and the :e! command will edit without saving the previous file. Without an argument :e uses the current file as the argument, so entering in just the command :e! with no file name is useful for undoing all of your changes to a file prior to the last save.

Split Windows

Vim also has a really nice feature (one of my favorites, in fact) called "split windows." It is invoked by using the :sp command with or without an optional filename argument (if no argument is given, it assumes the currently open file). It then splits the window into two parts and opens the new file in the new half. I use this for two purposes:

  1. If I'm editing a program and want a library file open for reference, I can see both files at once. This, of course, is just one example of many where having more than one file open at a time is useful.
  2. If I need to refer to another part of a file while I'm editing it, I can open the file itself in a split window. Vim is programmed well enough to update both windows when changes occur.
You can split windows as many times as you want (and your screen has space for). To close a window, use :q; to close all of them, use :qa to quit all.

Here are some useful commands when working with split windows:

KeyEffect
Ctrl-W Ctrl-WSwitches to the next window
Ctrl-W kSwitches to the window above
Ctrl-W jSwitches to the window below
Ctrl-W +Makes the window bigger by one line
Ctrl-W -Makes the window smaller by one line
The <Ctrl-W>+ and <Ctrl-W>- commands are often too slow to be used alone, but you can prefix them with a number, like other commands (12<Ctrl-W>+ to make the window really big).

Vim 6.1 introduces vertical splits, which allow you to split a window vertically rather than horizontally. I personally don't find it all that useful, but some people do. It's done with the :vs command.

We've now seen what Vi and Vim can do for you; now let's look at what you can to to Vim.

Next Page