I.T. Consulting
How RAID Works What's a RAID? Hardware vs Software RAID Striping and Mirroring RAID 2 and 3 RAID 4 and 5 Conclusion
Software RAID on Linux RAID: Quick Recap Software Tools Creating & Using an Array Monitoring an Array Removing & Re-Assembling an Array The mdadm.conf File Deleting an Array Summary & Cheat-Sheet
Network Security
Squid Proxy Server Basic Configuration Controlling Traffic Blocking Access Monitoring Traffic
SSH: Secure Shell Overview Using SSH Encryption Authentication Keys Configuring SSH Advanced Tricks
Implementing HTTPS What Is HTTPS? Setting Up The Server
Linux Skills
The ed Line Editor First Things First Navigating Entering Text Changing Text Line Maneuvers Text Searches Using ed in Real Life Summary
Regular Expressions Text Patterns Extended Expressions
The vi Editor Introduction Operating Modes Navigation Editing Summary
Intermediate vi Power Editing Cut-and-Paste Modifying Text Searches Tips & Tricks The vi Prompt Indenting
Creating an eBook Introduction Create an ePub Create a MOBI Create a PDF

Intermediate vi

This tutorial assumes you have completed the introductory vi Tutorial on this site, or that you have a basic familiarity with invoking vi, the concept of insert and command modes, inserting and deleting text, and navigating through a document.

In this tutorial, we will introduce more short-cuts as well as intermediate functions such as string searches, replacements, and cut-and-paste operations.

Upper-Case Commands

So far, we have introduced a number of command letters to perform various functions, including the following:

x Delete a character
w Move to next word
b Back to previous word
i Insert before cursor position
a Append after cursor position
o Open a line below cursor position

We did mention also that commands are case-sensitive, so that the above letters must all be used in lower-case.

Now, as a general rule, using the upper-case version of a command simply "amplifies" its meaning in some way. For instance, while i means "insert before the cursor," and upper-case I means "insert at the start of the line." It basically saves you the trouble to move to the start of the line before pressing "i" to insert text there.

Similarly, while a means "append after the cursor position," and upper-case A means "append at the end of the line." Again, this simply saves you a couple of keystrokes and is easy to remember.

Another example is the d command, which deletes the amount of text specified, as in dw to delete a word, for example. And upper-case D tells vi to delete all the text from the cursor position to the end of the line (equivalent to d$).

In some cases, the upper-case version of a command does not amplify its significance but rather reverses its direction. For instance, while x means "delete the next character," the upper-case command X means "delete the previous character."

And as you can probably guess by now, while o means "open a line below," the upper-case command O means "open a line above."

Navigation commands are also influenced by the case of the letter used. For instance, we know that w means to to next word, but the term "word" in this case is defined as the shortest part of a word. For instance, if the cursor is positioned at the start of a hyphenated expression like "sugar-free drink," pressing w will only move the cursor to the hyphen; pressing w again would move the cursor to the start of "free" and pressing it a third time would finally get you to the word "drink."

On the other hand, the upper-case W amplifies the concept of "word" to mean the entire hyphenated expression "sugar-free" and would jump right to the next "big" word, "drink."

The same applies to b, which takes you back to the beginning of a word. Again, when using the lower-case version, the meaning is "little word" as opposed to "big word" when using the upper-case B.

For instance, if the cursor is positioned on "drink" in the expression "sugar-free drink," pressing "b" the first time will take you to the beginning of "drink"; pressing it a second time will take you to the start of "free"; pressing it again will move it to the hyphen and pressing "b" a fourth time will move to the start of "sugar." Conversely, starting from the end again, pressing "B" the first time would take you to the start of "drink" and the second time would jump right to the start of "sugar."

Keep in mind that not all commands have a related upper-case version. For instance, while h is the command to move the cursor to the left, the upper-case command H means "go to the Home position," which means jump to the top of the screen. In this case, the two letters are not related at all. However, the general notion that upper-case commands are frequently related to their lower-case counterpart makes it easy to remember them.

Multiplying the Effect

Another consistent and powerful feature of vi is the ability to precede commands with a numeric value to multiply its effect.

For instance, while w takes you to the next word, the instruction 3w will move forward three words. Similarly, since dd means "delete this line," a command like 4dd would mean "delete four lines."

Note that the position of this numeric value (the "multiplier") is quite flexible. For instance, if dw means "delete word," you can type d2w to signify "delete two words," which would do the exact same thing as 2dw, which you would interpret as "twice delete word."

Splitting and Joining Lines

What if you need to split a long line into two shorted physical lines? Simply position the cursor where you want the split to take place, then press i to enter insert mode and press ENTER, which effectively inserts a carriage-return at this position in the text. You have just split up that line.

Note that you are still in insert mode, so you can either continue to type text at this point or just press <ESC> to return to command mode if you just wanted to split the line.

Can you guess how you would join two lines into one? Most people will guess that you simply need to delete the carriage-return at the end of the top line, but while this would be perfectly logical, that's not how it's done.

There is actually no way to delete a carriage-return using standard editing commands (like x for instance), so there is a special command just for joining lines: it's the upper-case J (for "join").

Here is another example where the upper-case version of a command has nothing to do with its lower-case counterpart, j, which means something totally unrelated (move down one line). In this case, the "J" was chosen simply for its mnemonic value for "join."

Screen Redraw

If, for some reason, your screen appears scrambled or things look out of sequence (for instance, perhaps you were working at the console and a system message has appeared on your screen), you can force a complete screen redraw by pressing <Ctrl-L> or <Ctrl-R>, depending on implementation (try them both to find which one works on your system).



Cut and paste

Whenever text is deleted in vi, that text goes to a temporary storage area in memory called the "buffer". Keeping this text in storage is what allows vi to undo modifications, but this feature can also be used to copy or move text.

The put Command

The contents of the buffer can be restored with the p (put) command, making it possible to perform cut-and-paste operations.

In its simplest form, you can move a character, word, line, or any amount of text by first deleting it, then positioning the cursor at another location in the file and pressing "p" to put back the contents of the buffer right where the cursor is.

For instance, let's bring up our sample file:

The universal laws of computer programming:

Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
Any given program will expand to fill all available memory.

To move law #1 past law #3 in this file, simply position the cursor on the line containing law #1 and type dd to delete it. Then, move the cursor down to the line containing law #3 and press p. The deleted line will be put back right below the cursor, resulting in this text (the relocated line is shown in bold):

The universal laws of computer programming:

If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
Any given program, when running, is obsolete.
Any given program will expand to fill all available memory.


  1. The buffer holds only your last deletion and is overwritten each time. For this reason, do not make any other deletions to the text prior to using the "p" command or the text in the buffer will be replaced and you will have lost your original text.
  2. The put command is context-sensitive. If the deletion was line-oriented (such as deleting an entire line), the text will be put back on the next line after the cursor position. If, on the other hand, the deletion was character-oriented (such as deleting a word), the text will be put back next to the cursor on the same line.
  3. As you might have expected, while p puts the contents of the buffer after the cursor position, the upper-case P puts the text before the cursor position (or above the current line instead of below, depending on context).

The upper-case version of the put command, "P", performs the same function but puts the text back before the cursor position or above the current line, depending on context.

Replicating Text

The contents of the buffer remain intact even after using "p" to put the text back. In other words, the buffer does not get cleared when using the "p" command. As a result, you can press "p" repeatedly to replicate the contents of the buffer as many times as you wish. This can be quite useful when creating tables or lists with similar lines, for instance.

Copying Text

The "yank" command, activated by pressing y, is very similar to the d command (delete) in that it copies the contents of the affected text in the buffer but does not delete the text.

The syntax for y is identical to that of d but it's used to copy text rather than delete it. For instance, you can "yank" two words using y2w (or 2yw, which is equivalent); this will place that amount of text in the buffer without affecting the current line. You can then move your cursor elsewhere and use p to put that text back where you want it, resulting in a copy-and-paste operation.

Just like you can use dd to delete a line, you can use yy to yank an entire line into the buffer, then "put" it somewhere else with p.

Want to copy 5 lines of text? Use 5yy, move to the desired spot in the file, then press p to put that buffer where desired.

IMPORTANT: Do not use 5p to put back those five lines. The "p" command tells vi to put the contents of the buffer at the current location, regardless of how much text is in the buffer. If you enter 5p, you are actually asking vi to do this operation 5 times, resulting in putting 5 copies of the buffer at the current location!

Consistent with the notion that an upper-case version of a command represents an "amplified" version of it, the upper-case Y command yanks the entire line that the cursor is positioned on. It is equivalent to yy.



Modifying Text

A simple method for modifying text is to delete it first, then insert new text in its place using the "i" (insert) command. However, there are better ways. We will examine three different instructions for modifying existing text: change, replace and substitute.

The change Command

The "c" (change) command combines the two functions of deleting then inserting text in a single operation. Like the "d" command, the change command requires a second character to specify the amount of text to be changed. For instance, the command "cw" applies to the text from the cursor position to the next word; "c$" would change the text from the cursor position to the end of the line.

Depending on the version of vi you are using, you may get a different visual cue to indicate that you are changing text. On older systems, a dollar sign would appear at the end of the text being modified to show you the amount of text you are about to replace. On newer systems, that amount of text immediately disappears.

In either case, as soon as you enter the change command, you are placed in insert mode and you can start typing the new text. Note that the new text does not have to be of the same length as the text being replaced. When finished, simply press <ESC> to return to command mode.

And just like "dd" deletes the entire line, "cc" replaces the entire line. Similarly, a numeric value can be used with the "c" command to multiply its effect; for instance, c2w will change two words.

The replace Command

The "r" (replace) command replaces a single character by another. While this may appear to be of very limited use, it is used surprisingly often to correct typo's. Simply position the cursor over the character to be replaced, hit "r", then type the substitute character. That's all. You are immediately returned to command mode after typing this character (you don't need to press <ESC>).

As expected, the upper-case "R" command has a similar function, except that it replaces any number of characters until you press <ESC>. In word processing terms, this is called "typeover", which means you simply type new text over existing text.

Note that this is different from the change command, which specified a given amount of text to modify. The "R" command simply overwrite existing text without boundaries; you need to press <ESC> to stop overwriting.

The substitute Command

The letter "s" is the command to substitute a single character for a string of any length. It is a cross between the r command, which replaces a single character, and the c command, which changes one string for another. In fact, the s command does the exact same thing as cl (change to one character on the right). It is most useful to correct misspellings, such as when a double consonant is required. For instance, in the following example, we misspelled the word "committee":

There was a meeting of the marketing comittee last night.

To correct this error, we would position the cursor over the "m" in "comittee", then press s to invoke the substitute command and type "mm," followed by <ESC> to return to command mode.

Editing to the End of the Line

Deleting or changing text from the cursor position to the end of the line is something we need to do so often that the author of vi has assigned single-letter commands to do so: pressing upper-case D deletes everything from the cursor position to the end of the line (equivalent to d$) while upper-case C changes all text from the cursor position to the end of the line (equivalent to c$ ).

Note that an upper-case "Y" does not yank text to the end of the line; it yanks the entire line. There is no apparent reason for this inconsistency.

Affecting the Entire Line

For the d, c and y commands, typing the letter twice means "take action on this whole line". Specifically, "dd" deletes the current line, "cc" changes the entire line, and "yy" yanks the entire line into the buffer.



Searching for text

A very useful feature of most editors is string searching. vi can perform text searches in a number of ways.

Forward Search

The most common requirement is to look for the next occurrence of a particular word or expression in the file. The forward slash (/) is used for this purpose. Simply press "/" and the cursor will move to the bottom of the screen, waiting for you to type in a string of text. Type the word or expression to look for, then press ENTER. The text you enter may be ordinary text or special text patterns called regular expressions.

vi will search the entire file forward for that string and position the cursor where the string has been found. If the end of file is reached before finding a match, the search will resume from the top of the file down to the location where the search originated, effectively searching the entire file. If no match has been found, a "** not found **" message will be displayed.


Text searches are case-sensitive unless otherwise specified with the :set ignorecase option, which we will examine later.

Backward Search

The same type of search can be done using the "?" command instead of the "/", but the search will be performed in the opposite direction.

Next search

Pressing "/" or "?" with no argument simply repeats the previous search in the same direction. An alternate way of doing the same thing is pressing "n" (next search); this is even easier since it requires a single keystroke and works for both forward and backward searches.



Tips and Tricks

Following are more features of vi which do not fit neatly under "Editing" or "Navigation", but which can be very useful nonetheless.

Toggling case

The tilde (~) character is used to toggle the case of characters. Pressing "~" will change the character at the cursor position from lower-case to upper-case, or vice-versa, then move to the next character. As a result, you can change the case of an entire word by simply holding the "~" key down and watching characters change in sequence.

Advanced Navigation

So far, we have learned how to move the cursor left or right using the h and l, respectively, or move the cursor up or down using k and j.

We have also learned how to skip one word at a time using w and b, and how to jump to the beginning or end of a line by pressing zero or the dollar sign.

The above is enough to get around, but there are many more navigation commands that you might find useful. Here are some of them:

Key Action
( Previous sentence
) Next sentence
{ Previous paragraph
} Next paragraph
H Top of screen ("High")
M Middle of screen
L Bottom of screen ("Low")

In addition, pressing upper-case G "goes" to the bottom of the file. In addition, preceding this letter with a number will jump to that line number. For instance, 1G goes to the top of the file (line #1) while 20G takes you to line #20.

Repeating a Modification

You can repeat a text modification, be it a deletion, insertion or change, by simply pressing the dot (.) key. For instance, if the last editing command you entered was dw to delete a word, you can repeat this action on a different word by moving the cursor where desired and pressing the dot.

This is particularly useful in conjunction with the search feature. For instance, let's say you need to replace every instance of the word "June" with "August" in a sales letter. You would first do a search for "June" using the slash (/) as we have seen earlier, which would bring the cursor to the first instance of "June." Using cw, you would replace that word with "August" and press <ESC> to return to command mode. That was your first change.

However, there might be 10 or more instances of "June" in that document, but the remaining ones will be extremely easy to modify. Simply press n for "next search," which will bring you to the next instance of the word "June," then press the dot. This will cause vi to repeat the last editing action, which was to replace the current word with "August." There, done. No need to press <ESC> since you are still in command mode.

Press n again, then dot, then n and dot again, repeatedly, until you have edited all instances.

The same strategy works if you need to insert text. For example, let's say you want to add the term "Year-End" in front of every instance of the exclamation "Sale!" in a flyer, making it "Year-End Sale!"

Simply search for the expression "Sale!" using the slash, then press i to enter insert mode, and type the words "Year-End" followed by a space, and then press <ESC>. You now have "Year-End Sale!". To repeat this edit for the next occurrence of "Sale!", just press n to repeat the search, then press dot to insert the same text in the same way you just did. Continue with "n" and dot repeatedly until you're done.

This technique is a great time-saver.

Inserting Control Characters

Occasionally, you may have to insert a control character such as <ESC> or a newline or a page break (Ctrl-L) into your text for whatever reason. Naturally, pressing <ESC> puts you back in command mode and pressing RETURN to insert a newline creates a new line, neither of which is the desired result.

To insert control codes, simply press Ctrl-v before entering the code. Ctrl-v is mnemonic for "verbatim". This tells vi to ignore the usual meaning of the next character and to take it "as is".

For instance, to insert the escape character into your text, enter insert mode by pressing i, then press Ctrl-v, then press <ESC>. Note that you are still in insert mode since the <ESC> was entered in your text as a normal character. It should show on the screen as "^[", but vi treats this pair as a single character.

You may continue entering text or you may press <ESC> a second time to return to command mode. Use the same technique for entering unusual control codes such as DEL (usually the interrupt character) or Ctrl-h (a backspace), for instance.



The vi ":" prompt

We have already mentioned that the commands ":w" and ":q" will save your file and exit the editor, respectively. You have noticed that pressing the colon (:) moves the cursor to the bottom of the screen, where you can complete the command by typing the appropriate letter.

The colon actually puts the editor in a line-oriented command mode from which a number of different functions are possible. Among other things, you can access the operating system, or set various options using the "set" command to change the way vi looks or operates, or enter sophisticated search-and-replace instructions (which are outside the scope of this tutorial).

In this section, we will examine a few of the most common instructions you may want to enter at the ":" prompt.

Saving Under a Different Name

We already know that ":w" saves your changes to the current file. However, what if you would prefer to save the file under a different name and leave the original unaffected?

You can specify a filename to the ":w" instruction, as in:

:w new_laws

This will save the current contents of the file under the name "new_laws." You could then quit the editor with ":q!" to avoid saving the changes to the original file, thus leaving it unchanged.


Be aware that if you later enter a regular ":w" command, you will be saving your changes to the original file, not to the new name you specified ("new_laws") in our example.

Saving a Portion of a File

What if you only want to save a portion of a file, like a paragraph for instance, instead of the entire file under a new filename? You can do this by specifying the line range you are interested in before the "w" command. For instance, to save lines 9 to 15 as the file "block.txt," you would enter this instruction:

:9,15w block.txt

How can you tell what the correct line numbers are for the block you want to save? That's covered in the next section.

vi Options

Numbering Lines

The way vi looks and operates can be modified by setting options using the "set" command. For instance, to display line numbers on-screen, use the "set number" option. Simply press the colon (:) to go to line mode (your cursor will move to the bottom of the screen), then enter "set number" as in this example:

The universal laws of computer programming:

Any given program, when running, is obsolete.
If a program is useful, it will have to be changed.
If a program is useless, it will have to be documented.
Any given program will expand to fill all available memory.
:set number

This will cause vi to display line numbers in front of each line of text, like this:

1 The universal laws of computer programming:
3 Any given program, when running, is obsolete.
4 If a program is useful, it will have to be changed.
5 If a program is useless, it will have to be documented.
6 Any given program will expand to fill all available memory.

Note that these line numbers cannot be edited; they are not part of the file, they are simply displayed for your convenience.

To turn off this feature, use set nonumber. As a general rule, most "set" options follow this convention: to turn them off, you simply prefix the instruction with "no."

In addition, most "set" options can be abbreviated. For instance, the set number command above may be abbreviated to set nu. Similarly, set nonumber may be abbreviated to set nonu.

Ignoring Case

We mentioned earlier that you can search for a string using the slash (/) command, and that such searches were case-sensitive. But what if you need to locate a particular string anywhere in the text and don't care whether it's in caps or lower-case, or any combination thereof?

For instance, what if you needed to locate all instances of the word "today" and didn't care whether it was entered as "Today," "today" or "TODAY"?

To tell vi to ignore case in searches, simply use the set ignorecase option, or set ic for short. To return to case-sensitive searches, simply enter set noignorecase, or set noic.

Showing the Mode

New users might like the set showmode option, which causes vi to display "-- INSERT --" at the bottom of the screen when in insert mode. When returning to command mode by pressing <ESC>, this message is cleared.

Showing Control Codes

Another useful option is set list, which displays all control codes and other "invisible" characters such as tabs or linefeeds.

Normally, tabs are not visibly discernable from other whitespace in vi, and there is also no easy way to tell whether there is whitespace at the end of a line of text. The "list" option displays control codes in a caret notation, such as "^I" for tabs or "^L" for form-feeds, for instance. In addition, this option displays a (non-editable) dollar sign at the end of each line of text to clearly show where it ends, making it clear whether there are trailing spaces.

For instance, here is what our sample file might look like after enabling the set list option:

The universal laws of computer programming:$
Any given program, when running, is obsolete.$
If a program is useful, it will have to be changed.   $
If a program is useless, it will have to be documented.$
Any given program will expand to fill all available memory.$
:set list

We now see that what appeared to be a blank line (line #2) actually contains three tab characters. We also see that line #4 contains some trailing spaces, and that we had a form-feed character (Ctrl-L) at the end of the file.

Note that these control codes can be edited out using standard vi commands. For instance, you can delete the unwanted tabs using the x command, as if they were regular text.

Although the editor displays each invisible control code as a pair of characters (a caret followed by a letter), they are treated internally as a single character. Therefore, to delete a tab using x, you only need to press x once per tab, not twice as if it were two characters.

Remember also that the dollar sign which is displayed to indicate the end of a line is only a display feature (like line numbers); there is no code there to delete.

Wrapping Text

By default, vi does not automatically break up your lines at the right margin when you're entering text. Unless you actually press ENTER to start a new line when you're approaching the right margin, vi will simply create a very long line as you keep typing.

Visually, this long line may look like multiple lines on the screen as the text wraps around to the next line, but since there is no carriage-return character on that line, it's handled as a single line of text internally.

This is actually desirable when writing code, but may be inconvenient when composing text (like this article, which was written entirely with vi). Fortunately, it is possible to instruct vi to automatically break up lines as you approach the right margin with the "wrapmargin" option.

This option must be assigned a numeric value, as in set wrapmargin=5, which would tell vi to break up the text on a word boundary when you get within 5 characters of the right margin.

This option may also be abbreviated to "wm".

To turn off this feature, set the option to zero (set wm=0). To see the current value of this option, invoke set wm without a value; vi will report the current value at the bottom of the screen, as in "wrapmargin=5".

Automatic Initialization

As you develop personal preferences, you may wish to use certain options every time you invoke vi. Rather than having to enter this options manually each time, you can store your favorite options in the file .vimrc (or .virc or .exrc on some systems) located in your home directory.

For example, let's say you always want vi to number lines and to wrap lines around near the right margin; you would create a .vimrc file in your home directory containing these lines:

set nu
set wm=5

That's it. From now on, every time you invoke vi, these options will be set automatically for your session.



Indenting Text

In programming, it is not unusual to indent code using tabs. While you can certainly enter those tabs manually as part of your code, you can also indent a line or a block of text using the ">" command at the vi prompt (you can think of it as an arrow pushing text to the right).

For instance, to indent the four laws of computer programming in our file, we could use the command "3,6>" to tell vi to indent lines 3 to 6, as shown here:

1 The universal laws of computer programming:
3 Any given program, when running, is obsolete.
4 If a program is useful, it will have to be changed.
5 If a program is useless, it will have to be documented.
6 Any given program will expand to fill all available memory.

which would result in this:

1 The universal laws of computer programming:
3       Any given program, when running, is obsolete.
4       If a program is useful, it will have to be changed.
5       If a program is useless, it will have to be documented.
6       Any given program will expand to fill all available memory.

To remove an indent, simply use the "<" instruction instead. For instance, to un-indent lines 4 and 4, you would enter 4,5<, which would result in this:

1 The universal laws of computer programming:
3       Any given program, when running, is obsolete.
4 If a program is useful, it will have to be changed.
5 If a program is useless, it will have to be documented.
6       Any given program will expand to fill all available memory.

By default, vi displays tabs as 8 spaces, although this is only a visual cue; internally, vi preserves the tab character rather than actually replacing it with spaces.

While the default is 8 spaces, we can tell vi to use any value we want using the "tabstop" option. For instance, to tell vi to expand tabs to 4 spaces, use set tabstop=4, or set ts=4 for short.

This feature is particularly useful when writing deeply nested code.

Where to go from here?

The features you have learned in this tutorial should allow you to comfortably and competently create and modify files of moderate complexity. If you are a professional programmer or writer and will be using vi on a daily basis, you will want to learn more about the extraordinary power of vi, and there is a lot more to discover.

The good news is that it's easier to learn the advanced features of vi than it was to learn the introduction, simply because there is a lot of consistency throughout.

If you're ready to harness the full power of vi, your next step is to learn the ed text editor, which is the precursor to vi and is capable of powerful global search-and-replace operations using regular expressions, which are covered in their own tutorial. You can invoke the ed command set from vi at any time from the colon prompt.


Did you find an error on this page or do you have a comment?