免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
91 [报告]
发表于 2008-06-11 14:45 |只看该作者
A slash (used as a delimiter in the global replacement
sequence) must be escaped with a backslash when it is part of
the pattern or replacement; use \/ to get /. An alternate way
to achieve this same effect is to use a different character as
the pattern delimiter. For example, you could make the above
replacement using colons as delimiters. (The delimiter colons
and the ex command colon are separate entities.) Thus:

:%s:/home/tim:/home/linda:g

This is much more readable.

3. Put HTML italicization codes around the word RETURN:
:%s:RETURN:<I>&</I>:g

Notice here the use of & to represent the text that was
actually matched, and, as just described, the use of colons as
delimiters instead of slashes.

4. Change all periods to semicolons in lines 1 to 10:
:1,10s/\./;/g

A dot has special meaning in regular expression syntax and
must be escaped with a backslash (\.).

5. Change all occurrences of the word help (or Help) to HELP:
:%s/[Hh]elp/HELP/g

or:

:%s/[Hh]elp/\U&/g

The \U changes the pattern that follows to all uppercase. The
pattern that follows is the repeated search pattern, which is
either help or Help.

6. Replace one or more spaces with a single space:
:%s/


*
/



/g

论坛徽章:
0
92 [报告]
发表于 2008-06-11 14:45 |只看该作者
Make sure you understand how the asterisk works as a special
character. An asterisk following any character (or following
any regular expression that matches a single character, such
as . or [a-z]) matches zero or more instances of that
character. Therefore, you must specify two spaces followed by
an asterisk to match one or more spaces (one space, plus
zero or more spaces).

7. Replace one or more spaces following a colon with two
spaces:
:%s/:


*/
:



/g

8. Replace one or more spaces following a period or a colon with
two spaces:
:%s/\([:.]\)


*/\
1



/g

Either of the two characters within brackets can be matched.
This character is saved into a hold buffer, using \( and \),
and restored on the right-hand side by the \1. Note that
within brackets a special character such as a dot does not
need to be escaped.

9. Standardize various uses of a word or heading:
:%s/^Note[
:s]*/Notes:


/g

The brackets enclose three characters: a space, a colon, and
the letter s. Therefore, the pattern Note[ s:] will match
Note , Notes or Note:. An asterisk is added to the pattern so
that it also matches Note (with zero spaces after it) and
Notes: (the already correct spelling). Without the asterisk,

论坛徽章:
0
93 [报告]
发表于 2008-06-11 14:46 |只看该作者
Note would be missed entirely and Notes: would be incorrectly
changed to Notes: :.

10. Delete all blank lines:
:g/^$/d

What you are actually matching here is the beginning of the
line (^) followed by the end of the line ($), with nothing in
between.

11.
Delete all blank lines, plus any lines that contain only
whitespace:
:g/^[


tab]*$/d

(In the line above, a tab is shown as tab.) A line may appear
to be blank, but may in fact contain spaces or tabs. The
previous example will not delete such a line. This example,
like the one above it, searches for the beginning and end of
the line. But instead of having nothing in between, the pattern
tries to find any number of spaces or tabs. If no spaces or
tabs are matched, the line is blank. To delete lines that
contain whitespace but that aren't empty, you would have to
match lines with at least one space or tab:

:g/^[


tab][


tab]*$/d

12. Delete all leading spaces on every line:
:%s/^


*\(.*\)/\1/

Use ^* to search for one or more spaces at the beginning
of each line; then use \(.*\) to save the rest of the line into
the first hold buffer. Restore the line without leading spaces,
using \1.

13. Delete all spaces at the end of every line:
:%s/\(.*\)

论坛徽章:
0
94 [报告]
发表于 2008-06-11 14:46 |只看该作者
*$/\1/

For each line, use \(.*\) to save all the text on the line, but
only up until one or more spaces at the end of the line.
Restore the saved text without the spaces.

The substitutions in this example and the previous one will
happen only once on any given line, so the g option doesn't
need to follow the replacement string.

14. Insert a > at the start of every line in a file:
:%s/^/>

/

What we're really doing here is "replacing" the start of the line
with > . Of course, the start of the line (being a logical
construct, not an actual character) isn't really replaced!

This command is useful when replying to mail or USENET
news postings. Frequently, it is desirable to include part of the
original message in your reply. By convention, the inclusion is
distinguished from your reply by setting off the included text
with a right angle bracket and a couple of spaces at the start
of the line. This can be done easily as shown above.
(Typically, only part of the original message will be included.
Unneeded text can be deleted either before or after the above
replacement.) Advanced mail systems do this automatically.
However, if you're using vi to edit your mail, you can do it
with this command.

15. Add a period to the end of the next six lines:
:.,+5s/$/./

The line address indicates the current line plus five lines. The
$ indicates the end of line. As in the previous example, the $
is a logical construct. You aren't really replacing the end of the
line.

16.
Reverse the order of all hyphen-separated items in a
list:
:%s/\(.*\)

论坛徽章:
0
95 [报告]
发表于 2008-06-11 14:47 |只看该作者
-



\(.*\)/\
2



-



-
\1/

Use \(.*\) to save text on the line into the first hold buffer,
but only until you find . Then use \(.*\) to save the rest
of the line into the second hold buffer. Restore the saved
portions of the line, reversing the order of the two hold
buffers. The effect of this command on several items is shown
below.

more - display files

becomes:

display files - more

and:

lp - print files

becomes:

print files - lp

17. Change every word in a file to uppercase:
:%s/.*/\U&/

or:

:%s/./\U&/g

The \U flag at the start of the replacement string tells vi to
change the replacement to uppercase. The & character replays
the text matched by the search pattern as the replacement.
These two commands are equivalent; however, the first form
is considerably faster, since it results in only one substitution
per line (.* matches the entire line, once per line), whereas
the second form results in repeated substitutions on each line
(. matches only a single character, with the replacement
repeated on account of the trailing g).

论坛徽章:
0
96 [报告]
发表于 2008-06-11 14:47 |只看该作者
18. Reverse the order of lines in a file:[8]
[8] From an article by Walter Zintz in UNIX World, May 1990.
:g/.*/mo0

The search pattern matches all lines (a line contains zero or
more characters). Each line is moved, one by one, to the top
of the file (that is, moved after imaginary line 0). As each
matched line is placed at the top, it pushes the previously
moved lines down, one by one, until the last line is on top.
Since all lines have a beginning, the same result can be
achieved more succinctly:

:g/^/mo0

19.
In a database, on all lines not marked Paid in full,
append the phrase Overdue:
:g!/Paid


in


full/s/$/Overdue/

or the equivalent:

:v/Paid
in


full/s/$/Overdue/

To affect all lines except those matching your pattern, add a !
to the g command, or simply use the v command.

20.
For any line that doesn't begin with a number, move the
line to the end of the file:
:g!/^[0-9]/m$

or:

:g/^[^0-9]/m$

As the first character within brackets, a caret negates the
sense, so the two commands have the same effect. The first
one says, "Don't match lines that begin with a number," and

论坛徽章:
0
97 [报告]
发表于 2008-06-11 14:48 |只看该作者
the second one says, "Match lines that don't begin with a
number."

21.
Change manually numbered section heads (e.g., 1.1,
1.2, etc.) to a troff macro (e.g., .Ah for an A-level heading):
:%s/^[1-9]\.[1-9]/.Ah/

The search string matches a digit other than zero, followed by
a period, followed by another non-zero digit. Notice that the
period doesn't need to be escaped in the replacement (though
a \ would have no effect, either). The command above won't
find chapter numbers containing two or more digits. To do so,
modify the command like this:

:%s/^[1-9][0-9]*\.[1-9]/.Ah/

Now it will match chapters 10 to 99 (digits 1 to 9, followed by
a digit), 100 to 999 (digits 1 to 9, followed by two digits), etc.
The command still finds chapters 1 to 9 (digits 1 to 9,
followed by no digit).

22.
Remove numbering from section headings in a
document. You want to change the sample lines:
23. 2.1 Introduction
10.3.8 New Functions
into the lines:

Introduction
New Functions


Here's the command to do this:

:%s/^[1-9][0-9]*\.[1-9][0-9.]
*
/
/



The search pattern resembles the one in the previous
example, but now the numbers vary in length. At a minimum,
the headings contain number, period, number, so you start
with the search pattern from the previous example:

[1-9][0-9]*\.[1-9]

But in this example, the heading may continue with any
number of digits or periods:


[0-9.]*

论坛徽章:
0
98 [报告]
发表于 2008-06-11 14:49 |只看该作者
of
24.
Change the word Fortran to the phrase FORTRAN
(acronym of FORmula TRANslation)
:
:%s/\(For\)\(tran\)/\U\1\2\E

(acronym

\U\1\Emula

\U\2\Eslation)/g

First, since we notice that the words FORmula and
TRANslation use portions of the original word, we decide to
save the search pattern in two pieces: \(For\) and \(tran\).
The first time we restore it, we use both pieces together,
converting all characters to uppercase: \U\1\2. Next, we
undo the uppercase with \E; otherwise the remaining
replacement text would all be uppercase. The replacement
continues with actual typed words, then we restore the first
hold buffer. This buffer still contains For, so again we convert
to uppercase first: \U\1. Immediately after, we lowercase the
rest of the word: \Emula. Finally, we restore the second hold
buffer. This contains tran, so we precede the "replay" with
uppercase, follow it with lowercase, and type out the rest of
the word: \U\2\Eslation).

6.5 A Final Look at Pattern Matching
We conclude this chapter by presenting sample tasks that involve
complex pattern-matching concepts. Rather than solve the
problems right away, we'll work toward the solutions step by step.

6.5.1 Deleting an Unknown Block of Text
Suppose you have a few lines with this general form:

the best of times; the worst of times: movingThe coolest of times; the worst of times: moving

The lines that you're concerned with always end with moving, but
you never know what the first two words might be. You want to
change any line that ends with moving to read:

The greatest of times; the worst of times: moving

论坛徽章:
0
99 [报告]
发表于 2008-06-11 14:49 |只看该作者
Since the changes must occur on certain lines, you need to specify a
context-sensitive global replacement. Using :g/moving$/ will match
lines that end with moving. Next, you realize that your search
pattern could be any number of any character, so the
metacharacters .* come to mind. But these will match the whole
line unless you somehow restrict the match. Here's your first
attempt:

:g/moving$/s/.*of/The

greatest
of/

This search string, you decide, will match from the beginning of the
line to the first of. Since you needed to specify the word of to
restrict the search, you simply repeat it in the replacement. Here's
the resulting line:

The greatest of times: moving

Something went wrong. The replacement gobbled the line up to the
second of instead of the first. Here's why. When given a choice, the
action of "match any number of any character" will match as much
text as possible. In this case, since the word of appears twice, your
search string finds:

the best of times; the worst of

rather than:

the best of

Your search pattern needs to be more restrictive:

:g/moving$/s/.*of times;/The greatest of times;/

Now the .* will match all characters up to the instance of the
phrase of times;. Since there's only one instance, it has to be the
first.

There are cases, though, when it is inconvenient, or even incorrect,
to use the .* metacharacters. For example, you might find yourself
typing many words to restrict your search pattern, or you might be
unable to restrict the pattern by specific words (if the text in the
lines varies widely). The next section presents such a case.

论坛徽章:
0
100 [报告]
发表于 2008-06-11 14:50 |只看该作者
6.5.2 Switching Items in a Database
Suppose you want to switch the order of all last names and first
names in a (text) database. The lines look like this:

Name: Feld, Ray; Areas: PC, UNIX; Phone: 123-4567Name: Joy, Susan S.; Areas: Graphics; Phone: 999-3333

The name of each field ends with a colon, and each field is
separated by a semicolon. Using the top line as an example, you
want to change Feld, Ray to Ray Feld. We'll present some
commands that look promising but don't work. After each
command, we show you the line the way it looked before the
change and after the change.

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

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

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

We've highlighted the contents of the first hold buffer in bold and
the contents of the second hold buffer in italic. Note that the first
hold buffer contains more than you want. Since it was not
sufficiently restricted by the pattern that follows it, the hold buffer
was able to save up to the second comma. Now you try to restrict
the contents of the first hold buffer:

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

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

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

Here you've managed to save the last name in the first hold buffer,
but now the second hold buffer will save anything up to the last
semicolon on the line. Now you restrict the second hold buffer, too:

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

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

Name: Ray Feld; Areas: PC, UNIX; Phone: 123-4567After
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP