macros for different classes of network
[unix-history] / .ref-BSD-3 / usr / doc / adv.ed / ae3
CommitLineData
8340f87c
BJ
1.NH
2LINE ADDRESSING IN THE EDITOR
3.PP
4The next general area we will discuss is that of
5line addressing in
6.UL ed ,
7that is, how you specify what lines are to be
8affected by editing commands.
9We have already used constructions like
10.P1
111,$s/x/y/
12.P2
13to specify a change on all lines.
14And most users are long since familiar with
15using a single newline (or return) to print the next line,
16and with
17.P1
18/thing/
19.P2
20to find a line that contains `thing'.
21Less familiar, surprisingly enough, is the
22use of
23.P1
24?thing?
25.P2
26to scan
27.ul
28backwards
29for the previous occurrence of `thing'.
30This is especially handy when you realize that the thing
31you want to operate on is back up the page from
32where you are currently editing.
33.PP
34The slash and question mark are the only characters you can
35use to delimit a context search, though you can use
36essentially any character in a substitute command.
37.SH
38Address Arithmetic
39.PP
40The next step is to combine the line numbers
41like `\*.', `$', `/.../' and `?...?'
42with `+' and `\-'.
43Thus
44.P1
45$-1
46.P2
47is a command to print the next to last line of
48the current file (that is, one line before line `$').
49For example, to recall how far you got in a previous editing session,
50.P1
51$-5,$p
52.P2
53prints the last six lines.
54(Be sure you understand why it's six, not five.)
55If there aren't six, of course, you'll get an error message.
56.PP
57As another example,
58.P1
59\&\*.-3,\*.+3p
60.P2
61prints from three lines before where you are now
62(at line dot)
63to three lines after,
64thus giving you a bit of context.
65By the way, the `+' can be omitted:
66.P1
67\&\*.-3,\*.3p
68.P2
69is absolutely identical in meaning.
70.PP
71Another area in which you can save typing effort
72in specifying lines is to use `\-' and `+' as line numbers
73by themselves.
74.P1
75-
76.P2
77by itself is a command to move back up one line in the file.
78In fact, you can string several minus signs together to move
79back up that many lines:
80.P1
81---
82.P2
83moves up three lines, as does `\-3'.
84Thus
85.P1
86-3,+3p
87.P2
88is also identical to the examples above.
89.PP
90Since `\-' is shorter than `\*.\-1',
91constructions like
92.P1
93-,\*.s/bad/good/
94.P2
95are useful. This changes `bad' to `good' on the previous line and
96on the current line.
97.PP
98`+' and `\-' can be used in combination with searches using `/.../' and `?...?',
99and with `$'.
100The search
101.P1
102/thing/--
103.P2
104finds the line containing `thing', and positions you
105two lines before it.
106.SH
107Repeated Searches
108.PP
109Suppose you ask for the search
110.P1
111/horrible thing/
112.P2
113and when the line is printed you discover that it
114isn't the horrible thing that you wanted,
115so it is necessary to repeat the search again.
116You don't have to re-type the search,
117for the construction
118.P1
119//
120.P2
121is a shorthand for `the previous thing that was searched for',
122whatever it was.
123This can be repeated as many times as necessary.
124You can also go backwards:
125.P1
126??
127.P2
128searches for the same thing,
129but in the reverse direction.
130.PP
131Not only can you repeat the search, but you can
132use `//' as the left side of a substitute command,
133to mean
134`the most recent pattern'.
135.P1
136/horrible thing/
137.ft I
138 .... ed prints line with `horrible thing' ...
139.ft R
140s//good/p
141.P2
142To go backwards and change a line, say
143.P1
144??s//good/
145.P2
146Of course, you can still use the `&' on the right hand side of a substitute to stand for
147whatever got matched:
148.P1
149//s//&\*B&/p
150.P2
151finds the next occurrence of whatever you searched for last,
152replaces it by two copies of itself,
153then prints the line just to verify that it worked.
154.SH
155Default Line Numbers and the Value of Dot
156.PP
157One of the most effective ways to speed up your editing
158is always to know what lines will be affected
159by a command if you don't specify the lines it is to act on,
160and on what line you will be positioned (i.e., the value of dot) when a command finishes.
161If you can edit without specifying unnecessary
162line numbers, you can save a lot of typing.
163.PP
164As the most obvious example, if you issue a search command
165like
166.P1
167/thing/
168.P2
169you are left pointing at the next line that contains `thing'.
170Then no address is required with commands like
171.UL s
172to make a substitution on that line,
173or
174.UL p
175to print it,
176or
177.UL l
178to list it,
179or
180.UL d
181to delete it,
182or
183.UL a
184to append text after it,
185or
186.UL c
187to change it,
188or
189.UL i
190to insert text before it.
191.PP
192What happens if there was no `thing'?
193Then you are left right where you were _
194dot is unchanged.
195This is also true if you were sitting
196on the only `thing' when you issued the command.
197The same rules hold for searches that use
198`?...?'; the only difference is the direction
199in which you search.
200.PP
201The delete command
202.UL d
203leaves dot pointing
204at the line that followed the last deleted line.
205When line `$' gets deleted,
206however,
207dot points at the
208.ul
209new
210line `$'.
211.PP
212The line-changing commands
213.UL a ,
214.UL c
215and
216.UL i
217by default all affect the current line _
218if you give no line number with them,
219.UL a
220appends text after the current line,
221.UL c
222changes the current line,
223and
224.UL i
225inserts text before the current line.
226.PP
227.UL a ,
228.UL c ,
229and
230.UL i
231behave identically in one respect _
232when you stop appending, changing or inserting,
233dot points at the last line entered.
234This is exactly what you want for typing and editing on the fly.
235For example, you can say
236.P1
237.ta 1.5i
238a
239 ... text ...
240 ... botch ... (minor error)
241\&\*.
242s/botch/correct/ (fix botched line)
243a
244 ... more text ...
245.P2
246without specifying any line number for the substitute command or for
247the second append command.
248Or you can say
249.P1 2
250.ta 1.5i
251a
252 ... text ...
253 ... horrible botch ... (major error)
254\&\*.
255c (replace entire line)
256 ... fixed up line ...
257.P2
258.PP
259You should experiment to determine what happens if you add
260.ul
261no
262lines with
263.UL a ,
264.UL c
265or
266.UL i .
267.PP
268The
269.UL r
270command will read a file into the text being edited,
271either at the end if you give no address,
272or after the specified line if you do.
273In either case, dot points at the last line read in.
274Remember that you can even say
275.UL 0r
276to read a file in at the beginning of the text.
277(You can also say
278.UL 0a
279or
280.UL 1i
281to start adding text at the beginning.)
282.PP
283The
284.UL w
285command writes out the entire file.
286If you precede the command by one line number,
287that line is written,
288while if you precede it by two line numbers,
289that range of lines is written.
290The
291.UL w
292command does
293.ul
294not
295change dot:
296the current line remains the same,
297regardless of what lines are written.
298This is true even if you say something like
299.P1
300/^\*e\*.AB/,/^\*e\*.AE/w abstract
301.P2
302which involves a context search.
303.PP
304Since the
305.UL w
306command is so easy to use,
307you should save what you are editing regularly
308as you go along
309just in case the system crashes, or in case you do something foolish,
310like clobbering what you're editing.
311.PP
312The least intuitive behavior, in a sense, is that of the
313.UL s
314command.
315The rule is simple _
316you are left sitting on the last line that got changed.
317If there were no changes, then dot is unchanged.
318.PP
319To illustrate,
320suppose that there are three lines in the buffer, and you are sitting on
321the middle one:
322.P1
323x1
324x2
325x3
326.P2
327Then the command
328.P1
329\&-,+s/x/y/p
330.P2
331prints the third line, which is the last one changed.
332But if the three lines had been
333.P1
334x1
335y2
336y3
337.P2
338and the same command had been issued while
339dot pointed
340at the second line, then the result
341would be to change and print only the first line,
342and that is where dot would be set.
343.SH
344Semicolon `;'
345.PP
346Searches with `/.../' and `?...?' start
347at the current line and move
348forward or backward respectively
349until they either find the pattern or get back to the current line.
350Sometimes this is not what is wanted.
351Suppose, for example, that the buffer contains lines like this:
352.P1
353 \*.
354 \*.
355 \*.
356 ab
357 \*.
358 \*.
359 \*.
360 bc
361 \*.
362 \*.
363.P2
364Starting at line 1, one would expect that the command
365.P1
366/a/,/b/p
367.P2
368prints all the lines from the `ab' to the `bc' inclusive.
369Actually this is not what happens.
370.ul
371Both
372searches
373(for `a' and for `b')
374start from the same point, and thus they both find the line
375that contains `ab'.
376The result is to print a single line.
377Worse, if there had been a line with a `b' in it
378before the `ab' line, then the print command
379would be in error, since the second line number
380would be less than the first, and it is illegal to
381try to print lines in reverse order.
382.PP
383This is because the comma separator
384for line numbers doesn't set dot as each address is processed;
385each search starts from the same place.
386In
387.UL ed ,
388the semicolon `;' can be used just like comma,
389with the single difference that use of a semicolon
390forces dot to be set at that point
391as the line numbers are being evaluated.
392In effect, the semicolon `moves' dot.
393Thus in our example above, the command
394.P1
395/a/;/b/p
396.P2
397prints the range of lines from `ab' to `bc',
398because after the `a' is found, dot is set to that line,
399and then `b' is searched for, starting beyond that line.
400.PP
401This property is most often useful in a very simple situation.
402Suppose you want to find the
403.ul
404second
405occurrence of `thing'.
406You could say
407.P1
408/thing/
409//
410.P2
411but this prints the first occurrence as well as the second,
412and is a nuisance when you know very well that it is only
413the second one you're interested in.
414The solution is to say
415.P1
416/thing/;//
417.P2
418This says to find the first occurrence of `thing', set dot to that line, then find the second
419and print only that.
420.PP
421Closely related is searching for the second previous
422occurrence of something, as in
423.P1
424?something?;??
425.P2
426Printing the third or fourth or ...
427in either direction is left as an exercise.
428.PP
429Finally, bear in mind that if you want to find the first occurrence of
430something in a file, starting at an arbitrary place within the file,
431it is not sufficient to say
432.P1
4331;/thing/
434.P2
435because this fails if `thing' occurs on line 1.
436But it is possible to say
437.P1
4380;/thing/
439.P2
440(one of the few places where 0 is a legal line number),
441for this starts the search at line 1.
442.SH
443Interrupting the Editor
444.PP
445As a final note on what dot gets set to,
446you should be aware that if you hit the interrupt or delete
447or rubout or break key
448while
449.UL ed
450is doing a command, things are put back together again and your state
451is restored as much as possible to what it was before the command
452began.
453Naturally, some changes are irrevocable _
454if you are reading or writing a file or making substitutions or deleting lines, these will be stopped
455in some clean but unpredictable state in the middle
456(which is why it is not usually wise to stop them).
457Dot may or may not be changed.
458.PP
459Printing is more clear cut.
460Dot is not changed until the printing is done.
461Thus if you print until you see an interesting line,
462then hit delete, you are
463.ul
464not
465sitting on that line or even near it.
466Dot is left where it was when the
467.UL p
468command was started.