Commit | Line | Data |
---|---|---|
b3f974bf BK |
1 | .H1 |
2 | Exercise 5: | |
3 | .H2 | |
4 | .PG | |
5 | Experiment with the substitute command. | |
6 | See what happens if you | |
7 | substitute for some word on a line with several occurrences of that word. | |
8 | For example, do this: | |
9 | .X1 | |
10 | a | |
11 | the other side of the coin | |
12 | .li | |
13 | \fB.\fR | |
14 | s/the/on the/p | |
15 | .X2 | |
16 | You will get | |
17 | .X1 | |
18 | on the other side of the coin | |
19 | .X2 | |
20 | A substitute command changes only the first occurrence of the first string. | |
21 | You can change all occurrences by adding a ``g'' (for ``global'') | |
22 | to the ``s'' command, like this: | |
23 | .X1 | |
24 | s/ . . . / . . . /gp | |
25 | .X2 | |
26 | Try other characters instead of slashes to delimit the two sets | |
27 | of characters in the ``s'' command \(mi anything should work | |
28 | except blanks or tabs. | |
29 | .PG | |
30 | (If you get funny results using any of the characters | |
31 | .X1 | |
32 | ^ \*. $ [ * \\ | |
33 | .X2 | |
34 | read the section on ``Special Characters''.) | |
35 | .H1 | |
36 | Context searching \(mi ``/ . . . /'' | |
37 | .H2 | |
38 | .PG | |
39 | With the substitute command mastered, we can move on to | |
40 | another highly important idea of | |
41 | .ul | |
42 | ed | |
43 | \(mi context searching. | |
44 | .PG | |
45 | Suppose we have our original three line text in the buffer: | |
46 | .X1 | |
47 | Now is the time | |
48 | for all good men | |
49 | to come to the aid of their party. | |
50 | .X2 | |
51 | Suppose we want to find the line that contains ``their'' so | |
52 | we can change it to ``the''. | |
53 | Now with only three lines in the buffer, it's pretty easy | |
54 | to keep track of what line the word ``their'' is on. | |
55 | But if the buffer contained several hundred lines, | |
56 | and we'd been making changes, deleting and rearranging lines, | |
57 | and so on, we would no longer really know what this line | |
58 | number would be. | |
59 | Context searching is simply a method of specifying the desired line, | |
60 | regardless of what its number is, | |
61 | by specifying some context on it. | |
62 | .PG | |
63 | The way we say ``search for a line | |
64 | that contains this particular string of characters'' | |
65 | is to type | |
66 | .X1 | |
67 | /\fIstring of characters we want to find\fP/ | |
68 | .X2 | |
69 | For example, | |
70 | the | |
71 | .ul | |
72 | ed | |
73 | line | |
74 | .X1 | |
75 | /their/ | |
76 | .X2 | |
77 | is a context search which | |
78 | is sufficient to find the desired line \(mi | |
79 | it will locate the next occurrence of | |
80 | the characters between slashes (``their''). | |
81 | It also sets dot to that line | |
82 | and prints the line for verification: | |
83 | .X1 | |
84 | to come to the aid of their party. | |
85 | .X2 | |
86 | ``Next occurrence'' means that | |
87 | .ul | |
88 | ed | |
89 | starts looking for the string at line ``\*.+1'', | |
90 | searches to the end of the buffer, | |
91 | then continues at line 1 and searches to line dot. | |
92 | (That is, the search ``wraps around'' from ``$'' to 1.) | |
93 | It scans all the lines in the buffer until it either finds the desired line | |
94 | or gets back to dot again. | |
95 | If the given string of characters can't be found in any line, | |
96 | .ul | |
97 | ed | |
98 | types the error message | |
99 | .X1 | |
100 | ? | |
101 | .X2 | |
102 | Otherwise it prints the line it found. | |
103 | .PG | |
104 | We can do both the search for the desired line | |
105 | .ul | |
106 | and | |
107 | a | |
108 | substitution all at once, like this: | |
109 | .X1 | |
110 | /their/s/their/the/p | |
111 | .X2 | |
112 | which will yield | |
113 | .X1 | |
114 | to come to the aid of the party. | |
115 | .X2 | |
116 | There were three parts to that last command: | |
117 | context search for the desired line, make the substitution, print the line. | |
118 | .PG | |
119 | The expression ``/their/'' is a context search expression. | |
120 | In their simplest form, | |
121 | all context search expressions are like this \(mi | |
122 | a string of characters surrounded by slashes. | |
123 | Context searches are interchangeable with line numbers, | |
124 | so they can be used by themselves to find and print a desired line, | |
125 | or as line numbers for some other command, like ``s''. | |
126 | We used them both ways in the examples above. | |
127 | .PG | |
128 | Suppose the buffer contains the three familiar lines | |
129 | .X1 | |
130 | Now is the time | |
131 | for all good men | |
132 | to come to the aid of their party. | |
133 | .X2 | |
134 | Then the | |
135 | .ul | |
136 | ed | |
137 | line numbers | |
138 | .X1 | |
139 | /Now/+1 | |
140 | /good/ | |
141 | /party/\(mi1 | |
142 | .X2 | |
143 | are all context search expressions, and they all refer | |
144 | to the same line (line 2). | |
145 | To make a change in line 2, | |
146 | we could say | |
147 | .X1 | |
148 | /Now/+1s/good/bad/ | |
149 | .X2 | |
150 | or | |
151 | .X1 | |
152 | /good/s/good/bad/ | |
153 | .X2 | |
154 | or | |
155 | .X1 | |
156 | /party/\(mi1s/good/bad/ | |
157 | .X2 | |
158 | The choice is dictated only by convenience. | |
159 | We could print all three lines by, for instance | |
160 | .X1 | |
161 | /Now/,/party/p | |
162 | .X2 | |
163 | or | |
164 | .X1 | |
165 | /Now/,/Now/+2p | |
166 | .X2 | |
167 | or by any number of similar combinations. | |
168 | The first one of these might be better if we don't | |
169 | know how many lines are involved. | |
170 | (Of course, if there were only three lines in the buffer, | |
171 | we'd use | |
172 | .X1 | |
173 | 1,$p | |
174 | .X2 | |
175 | but not if there were several hundred.) | |
176 | .PG | |
177 | The basic rule is: a context search expression is | |
178 | .ul | |
179 | the same as | |
180 | a line number, so it can be used wherever a line number is needed. | |
181 | .H1 | |
182 | Exercise 6: | |
183 | .H2 | |
184 | .PG | |
185 | Experiment with context searching. | |
186 | Try a body of text with | |
187 | several occurrences | |
188 | of the same string of characters, and scan through it using | |
189 | the same context search. | |
190 | .PG | |
191 | Try using context searches as line numbers for the | |
192 | substitute, print and delete commands. | |
193 | (They can also be used | |
194 | with ``r'', ``w'', and ``a''.) | |
195 | .PG | |
196 | Try context searching using ``?text?'' instead of ``/text/''. | |
197 | This scans lines in the buffer in reverse order | |
198 | rather than normal. | |
199 | This is | |
200 | sometimes useful if you go too far while looking for some | |
201 | string of characters \(mi it's an easy way to back up. | |
202 | .PG | |
203 | (If you get funny results with any of the characters | |
204 | .X1 | |
205 | ^ \*. $ [ * \\ | |
206 | .X2 | |
207 | read the section on ``Special Characters''.) | |
208 | .PG | |
209 | .ul | |
210 | Ed | |
211 | provides a shorthand for repeating a context search | |
212 | for the same string. | |
213 | For example, | |
214 | the | |
215 | .ul | |
216 | ed | |
217 | line number | |
218 | .X1 | |
219 | /string/ | |
220 | .X2 | |
221 | will find the next occurrence of ``string''. | |
222 | It often happens that this is not the desired line, | |
223 | so the search must be repeated. | |
224 | This can be done by typing merely | |
225 | .X1 | |
226 | // | |
227 | .X2 | |
228 | This shorthand stands for ``the most recently used | |
229 | context search expression.'' | |
230 | It can | |
231 | also be used as the first string of the substitute | |
232 | command, as in | |
233 | .X1 | |
234 | /string1/s//string2/ | |
235 | .X2 | |
236 | which will find the next occurrence of ``string1'' | |
237 | and replace it by ``string2''. | |
238 | This can save a lot of typing. | |
239 | Similarly | |
240 | .X1 | |
241 | ?? | |
242 | .X2 | |
243 | means ``scan backwards for the same expression.'' |