📄 ae2
字号:
with `the'.If you simply say .P1/the/.P2you will in all likelihood find several lines that contain `the' in the middle beforearriving at the one you want.But with.P1/^the/.P2you narrow the context, and thus arrive at the desired onemore easily..PPThe other use of `^' is of course to enable you to insertsomething at the beginning of a line:.P1s/^/\*B/.P2places a space at the beginning of the current line..PPMetacharacters can be combined. To search for aline that contains .ulonly the characters.P1\&\*.PP.P2you can use the command.P1/^\*e\*.PP$/.P2.SHThe Star `*'.PPSuppose you have a line that looks like this:.P1\fItext \fR x y \fI text \fR.P2where .ultext standsfor lots of text,and there are some indeterminate number of spaces between the.UL xand the.UL y .Suppose the job is to replace all the spaces between.UL xand.UL yby a single space.The line is too long to retype, and there are too many spacesto count.What now?.PPThis is where the metacharacter `*'comes in handy.A character followed by a starstands for as many consecutive occurrences of thatcharacter as possible.To refer to all the spaces at once, say.P1s/x\*B*y/x\*By/.P2The construction`\*B*'means`as many spaces as possible'.Thus `x\*B*y' means `an x, as many spaces as possible, then a y'..PPThe star can be used with any character, not just space.If the original example was instead.P1\fItext \fR x--------y \fI text \fR.P2then all `\-' signs can be replaced by a single spacewith the command.P1s/x-*y/x\*By/.P2.PPFinally, suppose that the line was.P1\fItext \fR x\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.y \fI text \fR.P2Can you see what trap lies in wait for the unwary?If you blindly type.P1s/x\*.*y/x\*By/.P2what will happen?The answer, naturally, is that it depends.If there are no other x's or y's on the line,then everything works, but it's blind luck, not good management.Remember that `\*.' matches.ulanysingle character?Then `\*.*' matches as many single characters as possible,and unless you're careful, it can eat up a lot more of the linethan you expected.If the line was, for example, like this:.P1\fItext \fRx\fI text \fR x\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.\*.y \fI text \fRy\fI text \fR.P2then saying.P1s/x\*.*y/x\*By/.P2will take everything from the.ulfirst`x' to the.ullast`y',which, in this example, is undoubtedly more than you wanted..PPThe solution, of course, is to turn off the special meaning of`\*.' with`\*e\*.':.P1s/x\*e\*.*y/x\*By/.P2Now everything works, for `\*e\*.*' means `as many.ulperiodsas possible'..PPThere are times when the pattern `\*.*' is exactly what you want.For example, to change.P1Now is the time for all good men .....P2into.P1Now is the time\*..P2use `\*.*' to eat up everything after the `for':.P1s/\*Bfor\*.*/\*./.P2.PPThere are a couple of additional pitfalls associated with `*' that you should be aware of.Most notable is the fact that `as many as possible' means.ulzeroor more.The fact that zero is a legitimate possibility issometimes rather surprising.For example, if our line contained.P1\fItext \fR xy \fI text \fR x y \fI text \fR.P2and we said.P1s/x\*B*y/x\*By/.P2the.ulfirst`xy' matches this pattern, for it consists of an `x',zero spaces, and a `y'.The result is that the substitute acts on the first `xy',and does not touch the later one that actually contains some intervening spaces..PPThe way around this, if it matters, is to specify a pattern like.P1/x\*B\*B*y/.P2which says `an x, a space, then as many more spaces as possible, then a y',in other words, one or more spaces..PPThe other startling behavior of `*' is again related to the factthat zero is a legitimate number of occurrences of somethingfollowed by a star. The command.P1s/x*/y/g.P2when applied to the line.P1abcdef.P2produces.P1yaybycydyeyfy.P2which is almost certainly not what was intended.The reason for this behavior is that zero is a legal numberof matches,and there are no x's at the beginning of the line(so that gets converted into a `y'),nor between the `a' and the `b'(so that gets converted into a `y'), nor ...and so on.Make sure you really want zero matches;if not, in this case write.P1s/xx*/y/g.P2`xx*' is one or more x's..SHThe Brackets `[ ]'.PPSuppose that you want to delete any numbersthat appearat the beginning of all lines of a file.You might first think of trying a series of commands like.P11,$s/^1*//1,$s/^2*//1,$s/^3*//.P2and so on,but this is clearly going to take forever if the numbers are at all long.Unless you want to repeat the commands over and over untilfinally all numbers are gone,you must get all the digits on one pass.This is the purpose of the brackets [ and ]..PPThe construction.P1[0123456789].P2matches any single digit _the whole thing is called a `character class'.With a character class, the job is easy.The pattern `[0123456789]*' matches zero or more digits (an entire number), so.P11,$s/^[0123456789]*//.P2deletes all digits from the beginning of all lines..PPAny characters can appear within a character class,and just to confuse the issue there are essentially no special charactersinside the brackets;even the backslash doesn't have a special meaning.To search for special characters, for example, you can say.P1/[\*.\*e$^[]/.P2Within [...], the `[' is not special.To get a `]' into a character class,make it the first character..PPIt's a nuisance to have to spell out the digits,so you can abbreviate them as[0\-9];similarly, [a\-z] stands for the lower case letters,and[A\-Z] for upper case..PPAs a final frill on character classes, you can specify a classthat means `none of the following characters'.This is done by beginning the class with a `^':.P1[^0-9].P2stands for `any character .ulexcepta digit'.Thus you might find the first line that doesn't begin with a tab or spaceby a search like.P1/^[^(space)(tab)]/.P2.PPWithin a character class,the circumflex has a special meaning only if it occurs at the beginning.Just to convince yourself, verify that.P1/^[^^]/.P2finds a line that doesn't begin with a circumflex..SHThe Ampersand `&'.PPThe ampersand `&' is used primarily to save typing.Suppose you have the line.P1Now is the time.P2and you want to make it.P1Now is the best time.P2Of course you can always say.P1s/the/the best/.P2but it seems silly to have to repeat the `the'.The `&' is used to eliminate the repetition.On the.ulrightside of a substitute, the ampersand means `whateverwas just matched', so you can say.P1s/the/& best/.P2and the `&' will stand for `the'.Of course this isn't much of a saving if the thingmatched is just `the', but if it is something truly long or awful,or if it is something like `.*'which matches a lot of text,you can save some tedious typing.There is also much less chance of making a typing errorin the replacement text.For example, to parenthesize a line,regardless of its length,.P1s/\*.*/(&)/.P2.PPThe ampersand can occur more than once on the right side:.P1s/the/& best and & worst/.P2makes.P1Now is the best and the worst time.P2and.P1s/\*.*/&? &!!/.P2converts the original line into.P1Now is the time? Now is the time!!.P2.PPTo get a literal ampersand, naturally the backslash is used to turn off the special meaning:.P1s/ampersand/\*e&/.P2converts the word into the symbol.Notice that `&' is not special on the left sideof a substitute, only on the.ulright side..SHSubstituting Newlines.PP.UL edprovides a facility for splitting a single line into two or more shorter lines by `substituting in a newline'.As the simplest example, suppose a line has gotten unmanageably longbecause of editing (or merely because it was unwisely typed).If it looks like.P1\fItext \fR xy \fI text \fR.P2you can break it between the `x' and the `y' like this:.P1s/xy/x\*ey/.P2This is actually a single command,although it is typed on two lines.Bearing in mind that `\*e' turns off special meanings,it seems relatively intuitive that a `\*e' at the end ofa line would make the newline thereno longer special..PPYou can in fact make a single line into several lineswith this same mechanism.As a large example, consider underlining the word `very'in a long lineby splitting `very' onto a separate line,and preceding it by the.UL roffor.UL nroffformatting command `.ul'..P1\fItext \fR a very big \fI text \fR.P2The command.P1s/\*Bvery\*B/\*e\&.ul\*every\*e/.P2converts the line into four shorter lines,preceding the word `very' by theline`.ul',and eliminating the spaces around the `very',all at the same time..PPWhen a newline is substitutedin, dot is left pointing at the last line created..PP.SHJoining Lines.PPLines may also be joined together,but this is done with the.UL jcommandinstead of.UL s .Given the lines.P1Now is\*Bthe time.P2and supposing that dot is set to the first of them,then the command.P1j.P2joins them together.No blanks are added,which is why we carefully showed a blank at the beginning of the second line..PPAll by itself,a.UL jcommandjoins line dot to line dot+1,but any contiguous set of lines can be joined.Just specify the starting and ending line numbers.For example,.P11,$jp.P2joins all the lines into one big oneand prints it.(More on line numbers in Section 3.).SHRearranging a Line with \*e( ... \*e).PP(This section should be skipped on first reading.)Recall that `&' is a shorthand that stands for whateverwas matched by the left side of an.UL scommand.In much the same way you can capture separate piecesof what was matched;the only difference is that you have to specifyon the left side just what pieces you're interested in..PPSuppose, for instance, that you have a file of lines that consist of names in the form.P1Smith, A. B.Jones, C..P2and so on,and you want the initials to precede the name, as in.P1A. B. SmithC. Jones.P2It is possible to do this with a series of editing commands,but it is tedious and error-prone.(It is instructive to figure out how it is done, though.).PPThe alternativeis to `tag' the pieces of the pattern (in this case,the last name, and the initials),and then rearrange the pieces.On the left side of a substitution,if part of the pattern is enclosed between\*e( and \*e),whatever matched that part is remembered,and available for use on the right side.On the right side,the symbol `\*e1' refers to whatevermatched the first \*e(...\*e) pair,`\*e2' to the second \*e(...\*e),and so on..PPThe command.P11,$s/^\*e([^,]*\*e),\*B*\*e(\*.*\*e)/\*e2\*B\*e1/.P2although hard to read, does the job.The first \*e(...\*e) matches the last name,which is any string up to the comma;this is referred to on the right side with `\*e1'.The second \*e(...\*e) is whatever followsthe comma and any spaces,and is referred to as `\*e2'..PPOf course, with any editing sequence this complicated,it's foolhardy to simply run it and hope.The global commands .UL gand .UL vdiscussed in section 4provide a way for you to print exactly thoselines which were affected by thesubstitute command,and thus verify that it did what you wantedin all cases.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -