Welcome to Linux Knowledge Base and Tutorial
"The place where you learn linux"
Linux Tracker

 Create an AccountHome | Submit News | Your Account  

Tutorial Menu
Linux Tutorial Home
Table of Contents
Up to --> Editing Files

· Vi
· vi Basics
· Changing Text in vi
· Moving Around in vi
· Searching in vi
· vi Buffers
· vi Magic
· Command Output in vi
· More vi Magic
· vi Odds and Ends
· Configuring vi

Man Pages
Linux Topics
Test Your Knowledge

Site Menu
Site Map
Copyright Info
Terms of Use
Privacy Info
Masthead / Impressum
Your Account

Private Messages
Recommend Us

News Archive
Submit News
User Articles
Web Links


The Web

Who's Online
There are currently, 243 guest(s) and 1 member(s) that are online.

You are an Anonymous user. You can register for free by clicking here

Linux Tutorial - Editing Files - Vi - vi Buffers
  Searching in vi ---- vi Magic  

vi Buffers

Remember when we first starting talking about searching, I mentioned that the expression you were looking for was held in a buffer. Also, whatever was matched by /[Bb][Oo][Aa][Tt] can be held in a buffer. We can then use that buffer as part of the replacement expression. For example, if we wanted to replace every occurrence of "UNIX" with "Linux," we could do it like this:


The scope of this command is defined by the %, the shortcut way of referring to the entire text. Or, you could first save "UNIX" into a buffer, then use it in the replacement expression. To enclose something in a buffer, we enclose it within a matching pair of back slashes \( and \) to define the extent of a buffer. You can even have multiple pairs that define the extent of multiple buffers. These are reference by \#, where # is the number of the buffer.

In this example

:%s/\(UNIX\)/Linux \1/g

the text "UNIX," is placed into the first buffer. You then reference this buffer with \1 to say to vi to plug in the contents of the first buffer. Because the entire search pattern is the same as the pattern buffer, you could also have written it like this

:%s/\(UNIX\)/Linux &/g

in which the ampersand represents the entire search pattern.

This obviously doesn't save much typing. In fact, in this example, it requires more typing to save "UNIX" into the buffer and then use it. However, if what you wanted to save was longer, you would save time. You also save time if you want to use the buffer twice. For example, assume you have a file with a list of other files, some of them C language source files. All of them end in .c. You now want to change just the names of the C files so that the ending is "old" instead of .c. To do this, insert mv at the beginning of each line as well as produce two copies of the file name: one with .c and one with .old. You could do it like this:

:%s/^\(.*\)\.c/mv \1.c \1.old/g

In English, this line says:

  • For every line (%)
  • substitute (s)
  • for the pattern starting at the beginning of the line (^), consisting of any number of characters ( \(.*\) ) (placing this pattern into buffer #1) followed by .c
  • and use the pattern mv, followed by the contents of buffer #1 (\1), followed by a .c, which is again followed by the contents of buffer #1, (\1) followed by .old
  • and do this for every line (g), (i.e., globally)

Now each line is of the form

mv file.c file.old

Note the slash preceeding the dot in the expression "\.c". The slash "protects" the dot from being interpreted as the metacharacter for "any character". Instead, you want to search for a literal dot, so you need to protect it.

We can now change the permissions to make this a shell script and execute it. We would then move all the files as described above.

Using numbers like this is useful if there is more that one search pattern that you want to process. For example, assume that we have a three-column table for which we want to change the order of the columns. For simplicity's sake, lets also assume that each column is separated by a space so as not to make the search pattern too complicated.

Before we start, we need to introduce a new concept to vi, but one that you have seen before: [ ]. Like the shell, the square bracket pair ([ ]) of vi is used to limit sets of characters. Inside of the brackets, the caret (^) takes on a new meaning. Rather than indicating the beginning of a line, here it negates the character we are searching for. So we could type

%s/\([^ ]*\) \([^ ]*\) \([^ ]*\)/\3 \1 \2/g

Here we have three regular expressions, all referring to the same thing: \([^ ]*\). As we discussed above, the slash pair \( and \) delimits each of the buffers, so everything inside is the search pattern. Here, we are searching for [^ ]*, which is any number of matches to the set enclosed within the brackets. Because the brackets limit a set, the set is ^, followed by a space. Because the ^ indicates negation, we are placing any number of characters that is not a space into the buffer. In the replacement pattern, we are telling vi to print pattern3, a space, pattern1, another space, then pattern2.

In the first two instances, we followed the pattern with a space. As a result, those spaces were not saved into any of the buffers. We did this because we may have wanted to define our column separator differently. Here we just used another space.

I have often had occasion to want to use the pattern buffers more than once. Because they are not cleared after each use, you can use them as many times as you want. Using the example above, if we change it to

%s/\([^ ]*\) \([^ ]*\) \([^ ]*\)/\3 \1 \2 \1/g

we would get pattern3, then pattern1, then pattern2, and at the end, pattern1 again.

Believe it or not, there are still more buffers. In fact, there are dozens that we haven't touched on. The first set is the numbered buffers, which are numbered 1-9. These are used when we delete text and they behave like a stack. That is, the first time we delete something, say a word, it is placed in buffer number 1. We next delete a line that is placed in buffer 1 and the word that was in buffer 1 is placed in buffer 2. Once all the numbered buffers all full, any new deletions push the oldest ones out the bottom of the stack and are no longer available.

To access these buffers, we first tell vi that we want to use one of the buffers by pressing the double-quote ("). Next, we specify then the number of the buffer, say 6, then we type either p or P to put it, as in "6p. When you delete text and then do a put without specifying any buffer, it automatically comes from buffer 1.

There are some other buffers, in fact, 26 of them, that you can use by name. These are the named buffers. If you can't figure out what their names are, think about how many of them there are (26). With these buffers, we can intentionally and specifically place something into a particular buffer. First, we say which buffer we want by preceding its name with a double-quote ("); for example, "f. This says that we want to place some text in the named buffer f. Then, we place the data in the buffer, for example, by deleting an entire line with dd or by deleting two words with d2w. We can later put the contents of that buffer with "fp. Until we place something new in that buffer, it will contain what we originally deleted.

If you want to put something into a buffer without having to delete it, you can. You do this by "yanking it." To yank an entire line, you could done one of several things. First, there is yy. Next, Y. Then, you could use y, followed by a movement commands, as in y-4, which would yank the next four lines (including the current one), or y/expression, which would yank everything from your current position up to and including expression.

To place yanked data into a named buffer (rather than the default buffer, buffer number 1), it is the same procedure as when you delete. For example, to yank the next 12 lines into named buffer h, we would do "h12yy. Now those 12 lines are available to us. Keep in mind that we do not have to store full lines. Inputting "h12yw will put the next 12 words into buffer h.

Some of the more observant readers might have noticed that because there are 26 letters and each has both an upper- and lowercase, we could have 52 named buffers. Well, up to now, the uppercase letters did something different. If uppercase letters were used to designate different buffers, then the pattern would be compromised. Have no fear, it is.

Instead of being different buffers than their lowercase brethren, the uppercase letters are the same buffer. The difference is that yanking or deleting something into an uppercase buffer appends the contents rather that overwriting them.

You can also have vi keep track of up to 26 different places with the file you are editing. These functions are just like bookmarks in word processors. (Pop quiz: If there 26 of them, what are their names?)

To mark a spot, move to that place in the file, type m for mark (what else?), then a single back quote (`), followed by the letter you want to use for this bookmark. To go back to that spot, press the back quote (`), followed by the appropriate letter. So, to assign a bookmark q to a particular spot, you would enter `q. Keep in mind that reloading the current file or editing a new one makes you lose the bookmarks.

Note that with newer version of vi (particularly vim) you don't press the backquote to set the mark, just m followed by the appropriate letter.

 Previous Page
Searching in vi
  Back to Top
Table of Contents
Next Page 
vi Magic


Test Your Knowledge

User Comments:

You can only add comments if you are logged in.

Copyright 2002-2009 by James Mohr. Licensed under modified GNU Free Documentation License (Portions of this material originally published by Prentice Hall, Pearson Education, Inc). See here for details. All rights reserved.
Show your Support for the Linux Tutorial

Purchase one of the products from our new online shop. For each product you purchase, the Linux Tutorial gets a portion of the proceeds to help keep us going.



Security Code
Security Code
Type Security Code

Don't have an account yet? You can create one. As a registered user you have some advantages like theme manager, comments configuration and post comments with your name.

Help if you can!

Amazon Wish List

Did You Know?
The Linux Tutorial can use your help.


Tell a Friend About Us

Bookmark and Share

Web site powered by PHP-Nuke

Is this information useful? At the very least you can help by spreading the word to your favorite newsgroups, mailing lists and forums.
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters. Articles are the property of their respective owners. Unless otherwise stated in the body of the article, article content (C) 1994-2013 by James Mohr. All rights reserved. The stylized page/paper, as well as the terms "The Linux Tutorial", "The Linux Server Tutorial", "The Linux Knowledge Base and Tutorial" and "The place where you learn Linux" are service marks of James Mohr. All rights reserved.
The Linux Knowledge Base and Tutorial may contain links to sites on the Internet, which are owned and operated by third parties. The Linux Tutorial is not responsible for the content of any such third-party site. By viewing/utilizing this web site, you have agreed to our disclaimer, terms of use and privacy policy. Use of automated download software ("harvesters") such as wget, httrack, etc. causes the site to quickly exceed its bandwidth limitation and are therefore expressly prohibited. For more details on this, take a look here

PHP-Nuke Copyright © 2004 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Page Generation: 0.10 Seconds