<TBODY>
</TBODY>
Firstly, I'd like to thank everybody who mailed me about my last
vi tutorial for their kind words - and for asking for more! I
also want to clarify that I am not using vi itself but the better
known clone called 'vim' which has been ported to a number of
different operating systems (Linux, Beos, VMS, DOS, Windows and
Amiga to name but a few) and is available for download at the vim
website, <A href="http://www.vim.org/">http://www.vim.org/</A>. I'm
mentioning this because there is a chance that I might accidentally
describe some vim specific functionality and would greatly
appreciate it if corrections were emailed to me. Anyways, time to
get on with it...
Lines. There is one mildly annoying thing about vi, which is
that for the most part you don't know for certain if one line of
text is displayed as just one line or whether it might be so long as
to wrap around and be displayed on the screen as being two or more
lines. This can be extremely annoying if for example you delete four
lines and, due to word wrap, you really only should have deleted
two. For this reason it would be rather nice to know where the
lines end and how to do something about it. Doing the first is
quite simple - type :set list to see where the lines end
(which will be indicated with dollar signs, tabs indicated with
'^I') and :set nolist to get the display back to
normal. Getting vi to do something about it preemptively is
rather simple too. All that you need do is type :set
wrapmargin=1 to make vi force lines not to wrap, this is a
really useful command which probably should be included in your
.exrc file. If for some reason you want to undo this, just type
:set wrapmargin=0. You could also use :set wrap and
:set nowrap for turning wordwrap on and off.
Seek and Find. One thing that I was asked to cover was
searching for text - and replacing it. On the face of it, searching
for text is fairly simple. Press / then type in the text that
you want found, pressing return afterwards. To find the next
occurrance of the same text just press / and return again. Using
/ means that the search text will be looked for further into the
file that you are editing - if you want vi to search in the other
direction then use the question mark (and again you can use ?
followed by the return key to search for the previous occurrance of
the text you are searching for). If you are alternating between
forward and reverse searches you don't have to specify the search
text a second time. For example, let's say you were looking for
the word 'spam' and you accidentally hit / and the return key before
you can read anything else and are shown the next occurrance of
'spam'. You don't have to type ?spam - ? on it's own will
suffice. You can also use 'n' and 'N' for searching in the same
direction and the alternate. There's one particular
disadvantage/annoyance about this though. If you look for the word
'to' vi will find it all over the place as a portion of longer words
(try looking for 'to' in "Going towards oblivion tomorrow too!").
There are a number of ways that you can solve this problem. Once
you find the first correct occurrance of the word you can use
'*' to find the next occurrance of it as a whole word. (*
will search forwards, # will search backwards.) What if you
are nowhere near the first occurance of the whole word? To solve
this you have to wrap the text you are looking for with angle
brackets - which you have to 'escape' with '\'. For example,
if you want VI to search for the word 'tux' and don't want the word
'tuxedos' to be found, this is what you'd type:
/\<tux\> followed by the return key. This solution is
the better one, mostly because you can use it to search for a phrase
or a certain combination of words like "if you". You can search
for regular expressions too, just like with sed so if you need to
find any number you can do /[0-9] and so on. Regular
expressions are much too complex for me to write about in this
tutorial, entire books have been written about them. Though of
course this mightn't stop me from writing a tutorial on them later
on. Don't hold your breath though!
Search and Replace. Lets say that you need to replace a word
with a different one. How would you do it? Here's how (this also
works on portions of words). Type :s/word/replacement/
(though the last / is really needed).
That works just fine
for replacing that word just once, if you need to do it a number of
times you need to use the g
modifier: :s/word/replacement/g Which is all well and
good if the word you want to replace only ever occurs on the same
line as the other occurrances. Fat chance of that in the real world.
So how do you do that then? What you can do is this, type :.,.+
and then a number followed by s/word/replace/g The number is taken
to be the number of lines that you want the substitute command to
process less one. So if I have a paragraph consisting of five lines
and I want to swap 'Fred' with 'Barney' I'd
use: :.,.+4s/Fred/Barney/g instead of moving to each
line and typing :& to repeat the last substitution. To do
this to every line in the file you can either use the hard way or
the easy way. I'm going to describe the hard way first - just for
the sake of completeness than for any other reason. What you need
to do is this: Go to the first line in the file (with 1G),
press <ctrl-G> to get vi tell you how many lines are in the
file (lets say it's 105) and then
use: :.,.+104s/Fred/Barney/g But this is way too
long-winded and is something that you'd rather not do. The
simplest way is to use: :%s/Fred/Barney/g You should be
aware though that this moves the insertion point to where the last
replacement occurred, so use := to find out which line you
have the insertion point on before you do anything so you can use
nG (where n is the line number) to get back to that line
straight away, with out any faffing around. That's great, but
what if you want to confirm which occurances of the word are
supposed to be replaced with the other word. How would you do that?
Setting this up is really quite simple, you need to use the confirm
modifier in conjunction with the global one (which is already
there). So you'd use :.,.+Ns/word/replacement/cg where N is
again the number of lines that you want affected (less/minus 1).
One particular thing that I was asked about is the annoying fact
that if you edit a text file which was edited under DOS or Windows
in your linux vi session there are a lot of weird ^M characters
displayed. If you are using vi to edit perl scripts or HTML pages
with JavaScript in them these ^M characters will cause problems.
These ^M characters are called Carriage Returns. You can use the
substitute command to get rid of these. Initially you might try to
do this with :%s/^M//g (where N is again the number of lines) This
simply won't work because the command is looking for two seperate
characters, '^' and 'M'. What you need to do is
this: :%s/<ctrl-v><return>//g What
<ctrl-v> does here is tell the substitute command that the
following keystroke is a part of the text to be replaced. So if you
wanted remove all tab characters from the document you could
use: :%/<ctrl-v><tab>//g
You insensitive... Bill Meyer asked me about case insensitive
searches. It's very simple to do a case insensitive search &
replace. All that it means is using the 'i' modifier. So to change
all occurrances of both 'betty' and 'Betty' to 'Wilma' you'd use
this: :%s/betty/Wilma/gi If though you want to change
all occurrances of 'ken' and 'Ken' to Kenneth, you have to be more
careful or you could have the word broken changed to broKenneth. All
you have to do is wrap the word being replaced with those escaped
angle brackets. :%s/\<ken\>/Kenneth/gi
You
might be tempted to try :/foo/i to find all occurrances of foo and
Foo or some such variation. But you'd be wrong. To do this
use :set ic and then perform your search (ic being an
abbreviation for 'ignore case'). If you then want to do a case
sensitive search you will need to use the following: :set
noic
Abbreviations & Autocorrect The support for abbreviations
in vi is really quite handy, both for taking shortcuts (for example
typing 'sw' as a word and having it replaced with the word
'software') and for correcting common spelling mistakes (replacing
'Adn' with 'And'). This is a very simple thing to do, for
example :ab sw software tells vi that everytime I type
sw as a whole word it will replace it with the word software.
Similarly I have a different abbreviation set up to replace
ailug with the words "Irish Linux Users' Group": :ab ailug
Irish Linux Users' Group You can see from this that you do
not have to escape the words that the abbreviation represents.
There's just one slight problem that you might encounter - if
you try to redefine an abbreviation, you'll find that the moment you
get as far as specifying what the abbreviation represents, that the
abbreviation itself will get expanded to the older
meaning/representation. You must unabbreviate an abbreviation before
you can redefine it. To do this type :una followed by the
name of the abbreviation and then redefine it. You can see a list of
all abbreviations that you have defined by using :ab on it's
own. Naturally you wouldn't want to type in a hoard of ab
commands each time that you open a file. It makes much more sense to
set up these abbreviations in a common file that vi can reference
when you start it, the .exrc file (or .vimrc if you're using vim).
This is a text file which can contain (amongst other things)
abbreviation commands and set commands (without the colon at the
start of the line).
Filters. One nice thing about vi is that you can filter your
document through an external program to replace it's text with the
output of the filter. Let me explain. Suppose you are
compiling a list of the reference books that you own (for whatever
reason). For example:
Perl Power!
CGI Programming in C & Perl
Information architecture for the World Wide Web
Perl 5 Desktop Reference
Webmaster in a nutshell
Linux in a nutshell
Perl Cookbook
HTML 3.2 plus How-To
The new hacker's dictionary (third edition)
Wouldn't it read better if it were in alphabetical order? And
even better if you did not have to order the titles of these books
'by hand'? To do it you should use the following,
:x,y!sort, where x is the line number where the list starts
and y is the line number where it ends. This would result with: CGI Programming in C & Perl
HTML 3.2 plus How-To
Information architecture for the World Wide Web
Linux in a nutshell
Perl 5 Desktop Reference
Perl Cookbook
Perl Power!
The new hacker's dictionary (third edition)
Webmaster in a nutshell
If you know the number of entries in the list and couldn't be
bothered to specify the line numbers you can type n!!sort
(note that the colon is missing and you should replace 'n' with the
number of entries that you want affected).
Word Count A better use of filters comes to mind, and that's
to get a word count of the document (1752 words and counting!). To
do this type: :%!wc This will display a group of three
numbers like, "206 1765 9995" (and pretty much nothing else). These
numbers indicate the number of lines, words and characters. To get
the document text back press 'u'.
Finishing Off Well that's pretty much it for now, between this
tutorial and the last one you should have an idea of how to edit
files in vi, how to find text, replace it and also how to use
filters to sort text alphabetically and get a word count. These
are the 'essentials' that I think should be know by anybody who
wants to use vi effeciently, though of course vi gurus are probably
shaking their heads in disbelief saying 'he didn't cover...'. As
always, please feel free to email me with corrections and anything
else that you think I ought to cover at a later stage [whether I
will or not is another matter - but there's always a chance].
Special Characters
source: "/usr/local" destination: "/usr/sbin"
%s/\"usr//local\"/\"/usr//sbin\"/g
so in front of special characters like html dump a "\" infront of it i.e. "
= \"
The Declan clause. This tutorial was written by <A
href="mailto:root@linux.ie">Ken Guest</A>, <A
href="http://technobrat.net/">http://technobrat.net/</A>. Copyright
© Ken Guest 1999. Publication of this work in any printed or
electronic form in part or in whole for non private use without (a)
the inclusion of the above copyright notice (b) written permission
of the author is an infringement of copyright and thus prohibited by
law and international convention.
Credits Thanks to: <A
href="mailto:bill.meyer@tellabs.spamspamspam.com">Bill Meyer</A>, <A
href="mailto:john.allen@oceanfree.spamspamspam.net">John Allen</A>,
<A href="mailto:robhill@indigo.spamspamspam.ie">Rob Hill</A> and <A
href="mailto:tethys@it.newsint.co.spamspamspam.uk">Tethys</A> for
corrections and guidance!
|