免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: projl
打印 上一主题 下一主题

《Learning the vi editor》 [复制链接]

论坛徽章:
0
101 [报告]
发表于 2008-06-11 14:50 |只看该作者
This gives you what you want, but only in the specific case of a
four-letter last name and a three-letter first name. (The previous
attempt included the same mistake.) Why not just return to the first
attempt, but this time be more selective about the end of the
search pattern?

:%s/: \(.*\), \(.*\); Area/: \2 \1; Area/

Name: Feld, Ray; Areas: PC, UNIX; Phone: 123-4567Before

Name: Ray Feld; Areas: PC, UNIX; Phone: 123-4567After

This works, but we'll continue the discussion by introducing an
additional concern. Suppose that the Area field isn't always present
or isn't always the second field. The above command won't work on
such lines.

We introduce this problem to make a point. Whenever you rethink a
pattern match, it's usually better to work toward refining the
variables (the metacharacters), rather than using specific text to
restrict patterns. The more variables you use in your patterns, the
more powerful your commands will be.

In the current example, think again about the patterns you want to
switch. Each word starts with an uppercase letter and is followed by
any number of lowercase letters, so you can match the names like
this:

[A-Z][a-z]*

A last name might also have more than one uppercase letter (McFly,
for example), so you'd want to search for this possibility in the
second and succeeding letters:

[A-Z][A-Za-z]*

It doesn't hurt to use this for the first name, too (you never know
when McGeorge Bundy will turn up). Your command now becomes:

:%s/: \([A-Z][A-Za-z]*\), \([A-Z][A-Za-z]*\);/: \2 \1;/

Quite forbidding, isn't it? It still doesn't cover the case of a name
like Joy, Susan S. Since the first-name field might include a middle
initial, you need to add a space and a period within the second pair
of brackets. But enough is enough. Sometimes, specifying exactly
what you want is more difficult than specifying what you don't want.

论坛徽章:
0
102 [报告]
发表于 2008-06-11 14:51 |只看该作者
In your sample database, the last names end with a comma, so a
last-name field can be thought of as a string of characters that are
not commas:

[^,]*

This pattern matches characters up until the first comma. Similarly,
the first-name field is a string of characters that are not semicolons:

[^;]*

Putting these more efficient patterns back into your previous
command, you get:

:%s/: \([^,]*\), \([^;]*\);/: \2 \1;/

The same command could also be entered as a context-sensitive
replacement. If all lines begin with Name, you can say:

:g/^Name/s/: \([^,]*\), \([^;]*\);/: \2 \1;/

You can also add an asterisk after the first space, in order to match
a colon that has extra spaces (or no spaces) after it:

:g/^Name/s/: *\([^,]*\), \([^;]*\);/: \2 \1;/

6.5.3 Using :g to Repeat a Command
As we've usually seen the :g command used, it selects lines that
are typically then edited by subsequent commands on the same
line鈥攆or example, we select lines with g, and then make
substitutions on them, or select them and delete them:

:g/mg[ira]box/s/box/square/g:g/^$/d

However, in his two-part tutorial in UNIX World,[9] Walter Zintz
makes an interesting point about the g command. This command
selects lines鈥攂ut the associated editing commands need not
actually affect the lines that are selected.

[9] Part 1, "vi Tips for Power Users," appears in the April 1990 issue of UNIX World. Part 2, "Using vi to
Automate Complex Edits," appears in the May 1990 issue. The examples presented are from Part 2.
Instead, he demonstrates a technique by which you can repeat ex
commands some arbitrary number of times. For example, suppose
you want to place ten copies of lines 12 through 17 of your file at
the end of your current file. You could type:

论坛徽章:
0
103 [报告]
发表于 2008-06-11 14:51 |只看该作者
:1,10g/^/ 12,17t$

This is a very unexpected use of g, but it works! The g command
selects line 1, executes the specified t command, then goes on to
line 2, to execute the next copy command. When line 10 is reached,
ex will have made ten copies.

6.5.4 Collecting Lines
Here's another advanced g example, again building on suggestions
provided in Zintz's article. Suppose you're editing a document that
consists of several parts. Part 2 of this file is shown below, using
ellipses to show omitted text and displaying line numbers for
reference:

Part 2

Capability Reference

.LP

Chapter 7

Introduction to the Capabilities

This and the next three chapters ...

... and a complete index at the end.

.LP

Chapter 8

Screen Dimensions

Before you can do anything useful

on the screen, you need to know ...

.LP

Chapter 9

Editing the Screen

This chapter discusses ...

.LP

Part 3:

Advanced Features

.LP

Chapter 10

The chapter numbers appear on one line, their titles appear on the
line below, and the chapter text (highlighted for emphasis) begins
on the line below that. The first thing you'd like to do is copy the
beginning line of each chapter, sending it to an already existing file
called begin.

Here's the command that does this:

:g /^Chapter/ .+2w >> begin

论坛徽章:
0
104 [报告]
发表于 2008-06-11 14:52 |只看该作者
You must be at the top of your file before issuing this command.
First you search for Chapter at the start of a line, but then you want
to run the command on the beginning line of each chapter鈥攖he
second line below Chapter. Because a line beginning with Chapter is
now selected as the current line, the line address .+2 will indicate
the second line below it. The equivalent line addresses +2 or ++
work as well. You want to write these lines to an existing file named
begin, so you issue the w command with the append operator >>.

Suppose you want to send the beginnings of chapters that are only
within Part 2. You need to restrict the lines selected by g, so you
change your command to this:

:/^Part 2/,/^Part 3/g /^Chapter/ .+2w >> begin

Here, the g command selects the lines that begin with Chapter, but
it searches only that portion of the file from a line starting with Part
2 through a line starting with Part 3. If you issue the above
command, the last lines of the file begin will read as follows:

This and the next three chapters ...
Before you can do anything usefulThis chapter discusses ...

These are the lines that begin Chapters 7, 8, and 9.

In addition to the lines you've just sent, you'd like to copy chapter
titles to the end of the document, in preparation for making a table
of contents. You can use the vertical bar to tack a second command
after your first command, like so:

:/^Part 2/,/^Part 3/g /^Chapter/ .+2w >> begin | +t$

Remember that with any subsequent command, line addresses are
relative to the previous command. The first command has marked
lines (within Part 2) that start with Chapter, and the chapter titles
appear on a line below such lines. Therefore, to access chapter titles
in the second command, the line address is + (or the equivalents +1
or .+1). Then use t$ to copy the chapter titles to the end of the file.

As these examples illustrate, thought and experimentation may lead
you to some unusual editing solutions. Don't be afraid to try things!
Just be sure to back up your file first!

论坛徽章:
0
105 [报告]
发表于 2008-06-11 14:53 |只看该作者
Chapter 7. Advanced Editing

This chapter introduces you to some of the more advanced
capabilities of the vi and ex editors. You should be reasonably
familiar with the material presented in the earlier chapters of this
book before you start working with the concepts presented in this
chapter.

This chapter is divided into five parts. The first part discusses a
number of ways to set options that allow you to customize your
editing environment. You'll learn how to use the set command and
how to create a number of different editing environments using
.exrc files.

The second part discusses how you can execute UNIX commands
from within vi, and how you can use vi to filter text through UNIX
commands.

The third part discusses various ways to save long sequences of
commands by reducing them to abbreviations, or even to
commands that use only one keystroke (this is called mapping
keys). It also includes a section on @-functions, which allow you to
store command sequences in a buffer.

The fourth part discusses the use of ex scripts from the UNIX
command line or from within shell scripts. Scripting provides a
powerful way to make repetitive edits.

The fifth part discusses some features of vi that are especially
useful to programmers. vi has options that control line indentation
and an option to display invisible characters (specifically tabs and
newlines). There are search commands that are useful with program
code blocks or with C functions.

7.1 Customizing vi
You have seen that vi operates differently on various terminals. (For
instance, on "dumb" terminals, vi inserts @ symbols in place of
deleted lines; on intelligent terminals, vi redraws the screen with
each edit.) On modern UNIX systems, vi gets operating instructions
about your terminal type from the terminfo terminal database. (On
older systems, vi uses the original termcap database.)[1]

[1] The location of these two databases varies from vendor to vendor. Try the commands man terminfo and
man termcap to get more information about your specific system.
There are also a number of options that you can set from within vi
that affect how it operates. For example, you can set a right margin

论坛徽章:
0
106 [报告]
发表于 2008-06-11 14:53 |只看该作者
that will cause vi to wrap lines automatically, so you don't need to
hit RETURN.

You can change options from within vi by using the ex command
:set. In addition, whenever vi is started up, it reads a file in your
home directory called .exrc for further operating instructions. By
placing :set commands in this file, you can modify the way vi acts
whenever you use it.

You can also set up .exrc files in local directories to initialize various
options that you want to use in different environments. For
example, you might define one set of options for editing English
text, but another set for editing source programs. The .exrc file in
your home directory will be executed first, then the one in your
current directory.

Finally, any commands stored in the shell variable EXINIT will be
executed by vi on startup. The settings in EXINIT take precedence
over those in the home directory .exrc file.

7.1.1 The :set Command
There are two types of options that can be changed with the :set
command: toggle options, which are either on or off, and options
that take a numeric or string value (such as the location of a margin
or the name of a file).

Toggle options may be on or off by default. To turn a toggle option
on, the command is:

:set option

To turn a toggle option off, the command is:

:set nooption

For example, to specify that pattern searches should ignore case,
type:

:set ic

If you want vi to return to being case-sensitive in searches, give the
command:

:set noic

论坛徽章:
0
107 [报告]
发表于 2008-06-11 14:54 |只看该作者
Some options have a value assigned to them. For example, the
window option sets the number of lines shown in the screen's
"window." You set values for these options with an equal sign (=):

:set window=20

During a vi session, you can check which options vi is using. The
command:

:set all

displays the complete list of options, including options that you have
set and defaults that vi has "chosen." The display should look
something like this:[2]

[2] The result of :set all depends very much on the version of vi you have. This is typical of UNIX vi; what
comes out of the various clones will be different.
autoindent nomodelines
noshowmode
autoprint nonumber
noslowopennoautowrite nonovice
tabstop=8beautify nooptimizetaglength=0directory=/var/tmp paragraphs=IPLPPPQPP LIpplpipnpbptags=tags /usr/lib/tags

noedcompatibletagstackerrorbells
term=vt102
prompt
noreadonly
noexrc redraw
noterse
flash
timeout
remap
hardtabs=8
ttytype=vt102noignorecasenolispwindow=23
report=3
scroll=11
sections=NHSHH HUuhsh+c
warn
nolist
wrapscanmagicwrapmargin=0nomesgnowriteany
shell=/bin/ksh
shiftwidth=8
showmatch

You can find out the current value of any individual option by name,
using the command:

论坛徽章:
0
108 [报告]
发表于 2008-06-11 14:54 |只看该作者
:set option?

The command:

:set

shows options that you have specifically changed, or set, either in
your .exrc file or during the current session.

For example, the display might look like this:

number sect=AhBhChDh window=20 wrapmargin=10

7.1.2 The .exrc File
The .exrc file that controls your own vi environment is in your home
directory (the directory you are in when you first log on). You can
modify the .exrc file with the vi editor, just as you can any other
text file.

If you don't yet have an .exrc file, simply use vi to create one. Enter
into this file the set, ab, and map commands that you want to have
in effect whenever you use vi or ex. (ab and map are discussed later
in this chapter.) A sample .exrc file might look like this:

set nowrapscan wrapmargin=7set sections=SeAhBhChDh nomesgmap q :w^M:n^Mmap v dwElpab ORA O'Reilly & Associates, Inc.

Since the file is actually read by ex before it enters visual mode (vi),
commands in .exrc need not have a preceding colon.

7.1.3 Alternate Environments
In addition to reading the .exrc file in your home directory, you can
allow vi to read a file called .exrc in the current directory. This
allows you to set options that are appropriate to a particular
project.

For example, you might want to have one set of options in a
directory mainly used for programming:

set number autoindent sw=4 terse
set tags=/usr/lib/tags

and another set of options in a directory used for text editing:

论坛徽章:
0
109 [报告]
发表于 2008-06-11 14:55 |只看该作者
set wrapmargin=15 ignorecase

Note that you can set certain options in the .exrc file in your home
directory and unset them in a local directory.

You can also define alternate vi environments by saving option
settings in a file other than .exrc and reading in that file with the
:so command. (so is short for source.)

For example:

:so .progoptions

Local .exrc files are also useful for defining abbreviations and key
mappings (described later in this chapter). When we write a book or
manual, we save all abbreviations to be used in that book in an
.exrc file in the directory in which the book is being created.


In all modern versions of vi, you have to first set
the exrc option in your home directory's .exrc file
before vi will read the .exrc file in the current
directory:

set exrc

This mechanism prevents other people from placing,
in your working directory, an .exrc file whose
commands might jeopardize the security of your
system.[3]

[3] The original versions of vi automatically read both files, if they existed. The exrc
option closes a potential security hole.
7.1.4 Some Useful Options
As you can see when you type :set all, there are an awful lot of
options that can be set. Many of them are used internally by vi and
aren't usually changed. Others are important in certain cases, but
not in others (for example, noredraw and window can be useful on a
dialup line at a low baud rate). The table in Section C.1 contains a
brief description of each option. We recommend that you take some
time to play with setting options鈥攊f an option looks interesting, try
setting it (or unsetting it) and watch what happens while you edit.
You may find some surprisingly useful tools.

As discussed earlier in this book, one option, wrapmargin, is
essential for editing non-program text. wrapmargin specifies the

论坛徽章:
0
110 [报告]
发表于 2008-06-11 14:55 |只看该作者
size of the right margin that will be used to autowrap text as you
type. (This saves manually typing carriage returns.) A typical value
is 7 to 15:

:set wrapmargin=10

Three other options control how vi acts when conducting a search.
Normally, a search differentiates between uppercase and lowercase
(foo does not match Foo), wraps around to the beginning of the file
(meaning that you can begin your search anywhere in the file and
still find all occurrences), and recognizes wildcard characters when
pattern matching. The default settings that control these options
are noignorecase, wrapscan, and magic, respectively. To change
any of these defaults, you would set the opposite toggle options:
ignorecase, nowrapscan, and nomagic.

Options that may be of particular interest to programmers include:
autoindent, showmatch, tabstop, shiftwidth, number, and list,
as well as their opposite toggle options.

Finally, consider using the autowrite option. When set, vi will
automatically write out the contents of a changed buffer when you
issue the :n (next) command to move to the next file to be edited,
and before running a shell command with :!.

7.2 Executing UNIX Commands
You can display or read in the results of any UNIX command while
you are editing in vi. An exclamation mark (!) tells ex to create a
shell and to regard what follows as a UNIX command:

:!command

So if you are editing and you want to check the time or date without
exiting vi, you can enter:

:!date

The time and date will appear on your screen; press RETURN to
continue editing at the same place in your file.

If you want to give several UNIX commands in a row without
returning to vi editing in between, you can create a shell with the ex
command:

:sh

When you want to exit the shell and return to vi, press CTRL-D.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP