免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
81 [报告]
发表于 2008-06-11 14:39 |只看该作者
\( \)

Saves the pattern enclosed between \( and \) into a special
holding space or "hold buffer." Up to nine patterns can be
saved in this way on a single line. For example, the pattern:

\(That\) or \(this\)

saves That in hold buffer number 1 and saves this in hold
buffer number 2. The patterns held can be "replayed" in
substitutions by the sequences \1 to \9. For example, to
rephrase That or this to read this or That, you could enter:

:%s/\(That\) or \(this\)/\2 or \1/

You can also use the \n notation within a search or substitute
string:

:s/\(abcd\)\1/alphabet-soup/

[4]
changes abcdabcd into alphabet-soup.

[4] This works with vi, nvi, and vim, but not with elvis 2.0, vile 7.4, or vile 8.0.
\< \>

Matches characters at the beginning (\<) or at the end (\>) of
a word. The end or beginning of a word is determined either
by a punctuation mark or by a space. For example, the
expression \<ac will match only words that begin with ac,
such as action. The expression ac\> will match only words
that end with ac, such as maniac. Neither expression will
match react. Note that unlike \(...\), these do not have to
be used in matched pairs.

~

Matches whatever regular expression was used in the last
search. For example, if you searched for The, you could
search for Then with /~n. Note that you can use this pattern
only in a regular search (with /).[5] It won't work as the
pattern in a substitute command. It does, however, have a
similar meaning in the replacement portion of a substitute
command.

[5] This is a rather flaky feature of the original vi. After using it, the saved search pattern is set to
the new text typed after the ~, not the combined new pattern, as one might expect. Also, none of
the clones behaves this way. So, while this feature exists, it has little to recommend its use.

论坛徽章:
0
82 [报告]
发表于 2008-06-11 14:39 |只看该作者
Several of the clones support optional, extended regular expression
syntaxes. See Section 8.4 for more information.

6.3.2 POSIX Bracket Expressions
We have just described the use of brackets for matching any one of
the enclosed characters, such as [a-z]. The POSIX standard
introduced additional facilities for matching characters that are not
in the English alphabet. For example, the French 猫 is an alphabetic
character, but the typical character class [a-z] would not match it.
Additionally, the standard provides for sequences of characters that
should be treated as a single unit when matching and collating
(sorting) string data.

POSIX also formalizes the terminology. Groups of characters within
brackets are called a "bracket expression" in the POSIX standard.
Within bracket expressions, beside literal characters such as a, !,
and so on, you can have additional components. These are:

论坛徽章:
0
83 [报告]
发表于 2008-06-11 14:40 |只看该作者
[:graph:] Printable and visible (non-space) characters
[:lower:] Lowercase characters
[:print:] Printable characters (includes whitespace)
[:punct:] Punctuation characters
[:space:] Whitespace characters
[:upper:] Uppercase characters
[digit:] Hexadecimal digits

You will have to do some research to determine if you have this
facility in your version of vi. You may need to use a special option to
enable POSIX compliance, have a particular environment variable
set, or use a version of vi that is in an unusual directory.

vi on HP-UX 9.x (and newer) systems support POSIX bracket
expressions, as does /usr/xpg4/bin/vi, on Solaris (but not
/usr/bin/vi). This facility is also available in nvi, and in elvis 2.1. As
commercial UNIX vendors become standards-compliant, expect to
see this feature become more widespread.

6.3.3 Metacharacters Used in Replacement Strings
When you make global replacements, the regular expressions above
carry their special meaning only within the search portion (the first
part) of the command.

For example, when you type this:

:%s/1\. Start/2. Next, start with $100/

note that the replacement string treats the characters . and $
literally, without your having to escape them. By the same token,
let's say you enter:

:%s/[ABC]/[abc]/g

If you're hoping to replace A with a, B with b, and C with c, you'll be
surprised. Since brackets behave like ordinary characters in a
replacement string, this command will change every occurrence of
A, B, or C to the five-character string [abc].

To solve problems like this, you need a way to specify variable
replacement strings. Fortunately, there are additional
metacharacters that have special meaning in a replacement string.

\ n

论坛徽章:
0
84 [报告]
发表于 2008-06-11 14:41 |只看该作者
Is replaced with text matched by the nth pattern previously
saved by \( and \), where n is a number from 1 to 9, and
previously saved patterns (kept in hold buffers) are counted
from the left on the line. See the explanation for \( and \)
earlier in this chapter.

\

Treats the following special character as an ordinary
character. Backslashes are metacharacters in replacement
strings as well as in search patterns. To specify a real
backslash, type two in a row (\\).

&

Is replaced with the entire text matched by the search pattern
when used in a replacement string. This is useful when you
want to avoid retyping text:

:%s/Yazstremski/&, Carl/

The replacement will say Yazstremski, Carl. The & can also
replace a variable pattern (as specified by a regular
expression). For example, to surround each line from 1 to 10
with parentheses, type:

:1,10s/.*/(&)/

The search pattern matches the whole line, and the &
"replays" the line, followed by your text.

~

Has a similar meaning as when it is used in a search pattern;
the string found is replaced with the replacement text
specified in the last substitute command. This is useful for
repeating an edit. For example, you could say
:s/thier/their/ on one line and repeat the change on
another with :s/thier/~/. The search pattern doesn't need
to be the same, though.

For example, you could say :s/his/their/ on one line and

[6]
repeat the replacement on another with :s/her/~/.

[6] Modern versions of the ed editor use % as the sole character in the replacement text to mean
"the replacement text of the last substitute command."
\u or \l

论坛徽章:
0
85 [报告]
发表于 2008-06-11 14:41 |只看该作者
Causes the next character in the replacement string to be
changed to uppercase or lowercase, respectively. For
example, to change yes, doctor into Yes, Doctor, you could
say:

:%s/yes, doctor/\uyes, \udoctor/

This is a pointless example, though, since it's easier just to
type the replacement string with initial caps in the first place.
As with any regular expression, \u and \l are most useful
with a variable string. Take, for example, the command we
used earlier:

:%s/\(That\) or \(this\)/\2 or \1/

The result is this or That, but we need to adjust the cases.
We'll use \u to uppercase the first letter in this (currently
saved in hold buffer 2); we'll use \l to lowercase the first
letter in That (currently saved in hold buffer 1):

:s/\(That\) or \(this\)/\u\2 or \l\1/

The result is This or that. (Don't confuse the number one with
the lowercase l; the one comes after.)

\U or \L and \e or \E

\U and \L are similar to \u or \l, but all following characters
are converted to uppercase or lowercase until the end of the
replacement string or until \e or \E is reached. If there is no
\e or \E, all characters of the replacement text are affected
by the \U or \L. For example, to uppercase Fortran, you could
say:

:%s/Fortran/\UFortran/

or, using the & character to repeat the search string:

:%s/Fortran/\U&/

All pattern searches are case-sensitive. That is, a search for the will
not find The. You can get around this by specifying both uppercase
and lowercase in the pattern:

/[Tt]he

You can also instruct vi to ignore case by typing :setic. See
Chapter 7, for additional details.

论坛徽章:
0
86 [报告]
发表于 2008-06-11 14:42 |只看该作者
6.3.4 More Substitution Tricks
You should know some additional important facts about the
substitute command:

1. A simple :s is the same as :s//~/. In other words, repeat the
last substitution. This can save enormous amounts of time
and typing when you are working your way through a
document making the same change repeatedly, but you don't
want to use a global substitution.
2. If you think of the & as meaning "the same thing" (as in what
was just matched), this command is relatively mnemonic. You
can follow the & with a g, to make the substitution globally on
the line, and even use it with a line range:
:%&g

repeat the last substitution everywhere

3. The & key can be used as a vi command to perform the :&
command, i.e., to repeat the last substitution. This can save
even more typing than :sRETURN; one keystroke versus
three.
4. The :~ command is similar to the :& command, but with a
subtle difference. The search pattern used is the last regular
expression used in any command, not necessarily the one
used in the last substitute command.
For example,[7] in the sequence:

[7] Thanks to Keith Bostic, in the nvi documentation, for this example.
:s/red/blue/
:/green
:
~


The :~ is equivalent to :s/green/blue/.

5. Besides the / character, you may use any non-alphanumeric,
non-whitespace character as your delimiter, except backslash,
double-quote, and the vertical bar (\, ", and |). This is
particularly handy when you have to make a change to a
pathname.
:%s;/user1/tim;/home/tim;g

6. When the edcompatible option is enabled, vi remembers the
flags (g for global and c for confirmation) used on the last
substitute, and applies them to the next one.

论坛徽章:
0
87 [报告]
发表于 2008-06-11 14:42 |只看该作者
This is most useful when you are moving through a file and
you wish to make global substitutions. You can make the first
change:

:s/old/new/g

:set edcompatible

After that, subsequent substitute commands will be global.

Despite the name, no known version of UNIX ed actually
works this way.

6.4 Pattern-Matching Examples
Unless you are already familiar with regular expressions, the
discussion of special characters above probably looks forbiddingly
complex. A few more examples should make things clearer. In the
examples that follow, a square ( ) is used to mark a space; it is not
a special character.

Let's work through how you might use some special characters in a
replacement. Suppose that you have a long file and that you want
to substitute the word child with the word children throughout that
file. You first save the edited buffer with :w, then try the global
replacement:

:%s/child/children/g

When you continue editing, you notice occurrences of words such as
childrenish. You have unintentionally matched the word childish.
Returning to the last saved buffer with :e!, you now try:

:%s/child

/children
/g

(Note that there is a space after child.) But this command misses
the occurrences child., child,, child: and so on. After some thought,
you remember that brackets allow you to specify one character
from among a list, so you realize a solution:

:%s/child[

,.;:!?]/children[
,.;:!?]/g

论坛徽章:
0
88 [报告]
发表于 2008-06-11 14:43 |只看该作者
This searches for child followed by either a space (indicated by ) or
any one of the punctuation characters ,.;:!?. You expect to
replace this with children followed by the corresponding space or
punctuation mark, but you've ended up with a bunch of punctuation
marks after every occurrence of children. You need to save the
space and punctuation marks inside a \( and \). Then you can
"replay" them with a \1. Here's the next attempt:

:%s/child\([


,.;:!?]\)/children\1/g

When the search matches a character inside the \( and \), the \1
on the right-hand side restores the same character. The syntax may
seem awfully complicated, but this command sequence can save
you a lot of work! Any time you spend learning regular expression
syntax will be repaid a thousandfold!

The command is still not perfect, though. You've noticed that
occurrences of Fairchild have been changed, so you need a way to
match child when it isn't part of another word.

As it turns out, vi (but not all other programs that use regular
expressions) has a special syntax for saying "only if the pattern is a
complete word." The character sequence \< requires the pattern to
match at the beginning of a word, whereas \> requires the pattern
to match at the end of a word. Using both will restrict the match to
a whole word. So, in the task given above, \<child\> will find all
instances of the word child, whether followed by punctuation or
spaces. Here's the substitution command you should use:

:%s/\<child\>/children/g

6.4.1 Search for General Class of Words
Suppose your subroutine names begin with the prefixes: mgi, mgr,
and mga.


If you want to save the prefixes, but want to change the name box
to square, either of the following replacement commands will do the
trick. The first example illustrates how \( and \) can be used to
save whatever pattern was actually matched. The second example
shows how you can search for one pattern but change another:

论坛徽章:
0
89 [报告]
发表于 2008-06-11 14:43 |只看该作者
:g/mg\([ira]\)box/s//mg\1square/g

The global replacement keeps track of whether an i, r or a is saved. In that way,
box is changed to square only when box is part of the routine's name.
:g/mg[ira]box/s/box/square/g

This has the same effect as the previous command, but it is a little less safe
since it could change other instances of box on the same line, not just those
within the routine names.
6.4.2 Block Move by Patterns
You can also move blocks of text delimited by patterns. For
example, assume you have a 150-page reference manual. Each
page is organized into three paragraphs with the same three
headings: SYNTAX, DESCRIPTION, and PARAMETERS. A sample of
one reference page follows:

.Rh 0 "Get status of named file" "STAT"
.Rh "SYNTAX"
.nf
integer*4 stat, retvalinteger*4 status(11)
character*123 filename
...
retval = stat (filename, status)
.fi
.Rh "DESCRIPTION"
Writes the fields of a system data structure into thestatus array.
These fields contain (among otherthings) information about the file's location, accessprivileges, owner, and time of last modification.
.Rh "PARAMETERS"
.IP "\fBfilename\fR" 15n
A character string variable or constant containingthe UNIX pathname for the file whose status you wantto retrieve.
You can give the ...

Suppose that it is decided to move DESCRIPTION above the
SYNTAX paragraph. With pattern matching, you can move blocks of
text on all 150 pages with one command!

:g /SYNTAX/.,/DESCRIPTION/-1 move /PARAMETERS/-1

论坛徽章:
0
90 [报告]
发表于 2008-06-11 14:44 |只看该作者
This command works as follows. First, ex finds and marks each line
that matches the first pattern (i.e., that contains the word SYNTAX).
Second, for each marked line, it sets . (dot, the current line) to that
line, and executes the command. Using the move command, the
command moves the block of lines from the current line (dot) to the
line before the one containing the word DESCRIPTION
(/DESCRIPTION/-1) to just before the line containing PARAMETERS
(/PARAMETERS/-1).

Note that ex can place text only below the line specified. To tell ex
to place text above a line, you first subtract one with -1, and then
ex places your text below the previous line. In a case like this, one
command saves literally hours of work. (This is a real-life example鈥
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP