Searching in vi
If you are trying to find a particular text,
you can get vi to do it for you. You tell vi that you want to enter a search pattern by pressing / (slash). This
will bring you down to the bottom line of the screen where you will see your slash. You then can type in what
you want to look for. When you press Enter, vi will start searching from your current location down toward the
bottom of the file. If you use press ? instead of /, then vi will search from your string toward the top of the file.
If the search is successful, that is, the string is found, you are brought to that point in the
If you decide that you want to search again, you have three choices.
You can press ? or / and input the search string again; press n, which is the first letter of the word
"next"; or simply press ? or / with no text following it for vi to
continue the search in the applicable direction. If you wanted to find the next string that matches
but in the opposite direction, what do you think the command would be? (Hint: the capital form of
the "next" command.)
Once you have found what you are looking for, you can edit the text
all you want and then continue searching. This is because the search string you entered is kept in
So, when you press /, ?, n, or N, the system remembers what you were looking for.
You can also include movement commands in these searches. First, you enclose the search pattern
with the character used to search (/ or ?), then add the movement command. For example,
if you wanted to search backward for the phrase "hard disk" and then move up a line, you would
enter ?hard disk?-. If you wanted to search forward for the phrase "operating system" and then
move down three lines, you would enter /operating system/+3.
All this time, we have been referring to the text
patterns as search strings. As you just saw, you can actually enter phrases. In fact, you can use any
regular expression you want when searching for patterns. For example, if you wanted
to search for the pattern "Linux," but only when it appears at the beginning of a line, you would
enter /^Linux. If you wanted to search for it at the end of the line, you
would enter /Linux$.
You can also do more complicated searches such as /^new [Bb][Oo][Aa][Tt], which will search for the word
"new" at the beginning of a line, followed by the word "boat" with each letter in either case.
No good text
editor would be complete without the ability to not only search for text but to replace it as well. One way of doing this
is to search for a pattern and then edit the text. Obviously, this starts to get annoying after the second or third instance
of the pattern you want to replace. Instead, you could combine several of the tools you have learned so far.
For example, lets say that everywhere in the text you wanted to replace "Unix" with "UNIX." First, do a search on
Unix with /Unix, tell vi that you want to change that word with cw, then input UNIX.
Now, search for the pattern again with /, and simply press . (dot). Remember that the dot command repeats your last
command. Now do the search and press the dot command again.
Actually, this technique is good if you have a pattern that you want to replace, but not every time it appears. Instead,
you want to replace the pattern selectively. You can just press n (or whatever) to continue the search without carrying
out the replacement.
What if you know that you want to replace every instance of a pattern with something else? Are you destined to
search and replace all 50 occurrences? Of course not. Silly you. There is another way.
Here I introduce what is referred to as escape or ex-mode, because the commands you enter are the same as in
the ex editor. To get to ex-mode, press : (colon). As with searches, you are brought down to the bottom of the screen.
This time you see the : (colon). The syntax is
: <scope> <command>
An example of this would be:
This tells vi the scope is lines 45 through 100. The command is s/Unix/UNIX/, which says you want to
substitute (s) the first pattern (Unix) with the second pattern (UNIX). Normally in English, we would say "substitute
for Unix." However, the order here is in keeping with the UNIX pattern of source first, then destination (or, what it was is
first, and what it will become is second, like mv source destination).
Note that this only replaces the first occurrence on each line. To get all occurrences, we must include g for
global at the end of each line, like this:
A problem arises if you want to modify only some of the occurrences. In this instance, you could add the
modifier c for confirm. The command would then look like this:
This causes vi to ask for confirmation before it makes the change.
If you wanted to search and replace on every line in the file, you could specify every line, such as :1,48.,
assuming there were 48 lines in the file. (By the way, use Ctrl-g to find out what line you are on and how many
lines there are in the file.) Instead of checking how many lines there are each time, you can simply use the
special character $ to indicate the end of the file. (Yes, $ also means the end of the line, but in this context,
it means the end of the file.) So, the scope of the command would look like :1,$.
Once again, the developers of vi made life easy for you. They realized that making changes throughout a
file is something that is probably done a lot. They included a special character to mean the entire file: %.
Therefore, the command is written as % = 1,$.
Here again, the search patterns can be regular expressions. For example, if we wanted to replace every
occurrence of "boat" (in either case) with the word "ship," the command would look like this:
As with regular expressions in other cases, you can use the asterisk (*) to mean any number of the
preceding characters or a period (.) to mean any single character. So, if you wanted to look for the word
"boat" (again, in either case), but only when it was at the beginning of a line and only if it were preceded
by at least one dash, the command would look like this:
The reason you have two dashes is that the search criteria specified at least one dash.
Because the asterisk can be any number, including zero, you must consider the case where
it would mean zero. That is, where the word "boat" was at the beginning of a line and there were no spaces.
If you didn't care what the character was as long as there was at least one, you could use the fact that in a
search context, a dot means any single character. The command would look like this: