Main index

Introducing UNIX and Linux


Overview
Using filters
      Collating sequence
      Character classes
Character-to-character transformation
Selecting lines by content
      Regular expressions
      Basic regular expressions
      Extended regular expressions
      Grep
Stream editor
      Sed addresses
Splitting a file according to context
Choosing between the three filters
More on Vi
Summary
Exercises

More on Vi

At this point, mention should be made of Vi commands which are almost identical to those of Sed, and which rely on BREs. First of all, / and ? are used for searching for strings. Followed by a BRE, each will locate the next (or previous) string matching that BRE. So, to move the cursor to the next blank line, and assuming you are in command-mode, type

/^$

or, if the apparently blank lines in your file may contain spaces also,

/^ *$

In colon-mode the commands available are, like Sed, of the form

address command arguments

Addresses constructed are the same as for Sed, with the addition of two extra symbols. These are ^, which means the first line of the file, and . (dot), denoting the current line as indicated by the cursor.

There is a command s ('substitute') which can be used to exchange occurrences of a string (denoted by a BRE) for another string. Suppose in the file you are editing, the cursor is on a line containing

Jack and Jill went up the hill

you could swap up for down by

:s/up/down/

The : gets you into colon-mode, s is the command to perform a substitution, and following s are three slashes. Between the first two is the BRE you wish to be changed. Between the final two is the string (just a string, not a BRE) it is to be changed to.

Normally, a substitution will occur once on the current line. That is, the address . is assumed by default. If the BRE to be substituted does not exist, then no change will happen. If you follow the command by a g ('global') the substitution will be made for all occurrences of the BRE on that line. So, to change all words on the current line commencing J to the string someone, you would type

:s/J[a-zA-Z]*/someone/g

Before a substitution command you can indicate which lines it is to be performed on by indicating an address explicitly. Preceding the command with % (percent) will cause it to be performed on every line in the file, but preceding it by a single line number will do the substitution on that line only. A pair of line numbers, separated by a comma, will apply the substitution to that range of lines. The start of the file is denoted by ^ and the end by $. Thus

:10,20s/Hello/Bonjour/

will substitute the first occurrence of HelloHello for Bonjour on lines 10 through 20 inclusive.

Worked example

You are using Vi to edit a file, and wish to change all occurrences of Chris to Sam on all lines.
Solution: Use the substitution command in colon-mode, apply it from the start of the file to the end, and globally on every line:

:^,$s/Chris/Sam/g

Be careful if your file contains (say) Christine - this solution changes it to Samtine

The symbol % can be used instead of ^,$ to mean the whole of the file.

The Vi colon mode commands which were discussed earlier can be preceded by an address and/or followed by arguments. The command w assumes the address %, and so will normally write the whole file; if a filename follows the w as an argument to the command, it will be that file written to, and the original file will remain unchanged. The command

:1,10w xyz

will write the first ten lines of the file to the file named xyz.

Often you will wish to perform an action on many lines, and the same action on each. The colon mode command g ('global') is used to apply a command to all lines matching a regular expression:
:g/BRE/action
For instance, to delete all completely empty lines,

:g/^$/d

or to insert an asterisk at the start of each line containing Chris

:g/Chris/s/^/*/

Copyright © 2002 Mike Joy, Stephen Jarvis and Michael Luck