0
|
1 *************************************************************
|
|
2 * BAWK Edition 3 - (Boisy's Awk) - Line processing utility
|
|
3 *
|
|
4 * (C) 1992 Boisy G. Pitre
|
|
5 *
|
|
6 * BAWK is a line processing utility "similar", but not exactly
|
|
7 * the same as the UNIX counterpart. For one, this version of BAWK is
|
|
8 * NOT a processing language. Its a line processing program. Don't
|
|
9 * get BAWK confused with AWK. They are two totally different programs.
|
|
10 *
|
|
11 * BAWK takes advantages of "fields" in lines of text. A field
|
|
12 * is a word or symbol, separated by whitespace. Each field is numbered
|
|
13 * sequentially from left to right. An example of how BAWK see's fields
|
|
14 * in lines of text:
|
|
15 *
|
|
16 * 1 2 3 4
|
|
17 * my name is boisy
|
|
18 *
|
|
19 * The numbers above the words in the line represent the field
|
|
20 * numbers. BAWK can extract any or all of these fields by their field
|
|
21 * number in any order, for a wide variety of useful formats. These formats
|
|
22 * can then be piped to another program or to a file for processing.
|
|
23 *
|
|
24 * Usage: BAWK [-a# -i -d? -l -f -F] "format field" [file] [...]
|
|
25 *
|
|
26 * NOTICE: Options are CASE SENSITIVE! Be aware of this when using BAWK.
|
|
27 *
|
|
28 * Opts:
|
|
29 * -d? = the optional delimiter you wish to use.
|
|
30 * Ex. to use a colon as a delimiter in addition to
|
|
31 * the already used space, use -d:
|
|
32 *
|
|
33 * -a# = Anchor start field to #th column.
|
|
34 *
|
|
35 * -i = prints lines even if the field doesn't exist.
|
|
36 * This option tells BAWK to print the format string even
|
|
37 * if the specified field is not found on the line.
|
|
38 * Default is OFF.
|
|
39 *
|
|
40 * -l = Prints the name of the file currently being scanned.
|
|
41 *
|
|
42 * -f = Forks a shell with the expanded line as a parameter. The
|
|
43 * expanded line buffer is NOT printed.
|
|
44 *
|
|
45 * -F = Forks a shell with the expanded line as a parameter, and
|
|
46 * prints the expanded line to StdOut.
|
|
47 *
|
|
48 * The format field can contain any characters you wish. The special
|
|
49 * character '$' is used to denote field positions. (Fields are from 1 to
|
|
50 * 255). If you wanted to extract the 5th field in a line, you would include
|
|
51 * $5 in the format string. BAWK would interpret this to be the fifth
|
|
52 * field, and would then expand it appropriately. Looking at the previous
|
|
53 * example:
|
|
54 *
|
|
55 * 1 2 3 4
|
|
56 * my name is boisy
|
|
57 *
|
|
58 * NOTE: there is a special field, $0, which denotes the ENTIRE
|
|
59 * input line.
|
|
60 *
|
|
61 * To tell BAWK to print the 3rd field in that line, the following
|
|
62 * command line would work:
|
|
63 *
|
|
64 * echo my name is boisy | bawk "$3"
|
|
65 *
|
|
66 * Note that the format string is ALWAYS contained in '"' quotes.
|
|
67 * You may also include non-specific info as part of the field. I use the
|
|
68 * following line in my /DD/SYS/CRONTAB file to stop my BBS at 7:00 each
|
|
69 * morning:
|
|
70 *
|
|
71 * procs | fgrep -i "tsmon" | bawk -f "kill $1"
|
|
72 *
|
|
73 * This line uses PROCS' output, and pipes it into FGREP. FGREP then
|
|
74 * throws away any lines that don't contain the word tsmon. The remaining
|
|
75 * lines that do contain the keyword are then piped to BAWK. BAWK takes the
|
|
76 * first field of that line (the Process ID number of tsmon), and combines
|
|
77 * it in a format whose output looks like: kill 3 (assuming 3 is the ID
|
|
78 * of the tsmon process). Finally, that line is used as a parameter for
|
|
79 * shell execution.
|
|
80 *
|
|
81 * You may also specify a filename or a list of them AFTER the format
|
|
82 * string. When using filenames, you can tell BAWK to print the name of the
|
|
83 * file it is currently scanning (to StdOut) using the -f option.
|
|
84 * To use '$' as a regular character in a format string, use $$.
|
|
85 * BAWK does not interpret this as the '$' field specifier.
|
|
86 *
|
|
87 * You can mix and match any number of fields for interesting
|
|
88 * combinations. If you prefer military time instead of DATE's regular
|
|
89 * output, try this:
|
|
90 *
|
|
91 * date | bawk -d, "$2 $1 $3"
|
|
92 *
|
|
93 * This example also introduced the -d option. This option allows
|
|
94 * you to specify another delimiter in addition to the already used space
|
|
95 * character. A good example of this would be finding the 5th field in
|
|
96 * the /DD/SYS/PASSWORD file, whose delimiter is a comma, NOT a space.
|
|
97 *
|
|
98 * Another useful option is -i. This allows the inclusion of printing
|
|
99 * the format string even though that field is not found on the line.
|
|
100 * Take the previous example again:
|
|
101 *
|
|
102 * 1 2 3 4
|
|
103 * my name is boisy
|
|
104 *
|
|
105 * The following command line would print nothing:
|
|
106 * echo my name is boisy | bawk "Name $5"
|
|
107 *
|
|
108 * BUT this line will output 'Name ':
|
|
109 * echo my name is boisy | bawk -i "Name $5"
|
|
110 *
|
|
111 * Keep in mind that if the -i option is not used, NO lines will
|
|
112 * be printed unless ALL fields are qualified.
|
|
113 *
|
|
114 *
|
|
115 * One other option worth noting is the -a option. This option sets
|
|
116 * an "anchor" to the #th column. Using our infamous example:
|
|
117 *
|
|
118 * 1 2 3 4
|
|
119 * my name is boisy
|
|
120 *
|
|
121 * The following command line would print 'name' because the anchor
|
|
122 * is set to the 3rd column (which is a space, ignored by BAWK):
|
|
123 * echo my name is boisy | bawk -a3 "$1"
|
|
124 *
|
|
125 * To print the names of all the modules in block $3F using MDIR:
|
|
126 * mdir e | grep "3F" | bawk "Module: $8"
|
|
127 *
|
|
128 * BAWK has very useful applications, making it a worthy addition to
|
|
129 * your OS-9 toolbox. In addition to these features, BAWK works GREAT with
|
|
130 * Shell+'s wildcards!
|
|
131 *
|
|
132 *
|
|
133 * By: Boisy G. Pitre
|
|
134 * Southern Station, Box 8455
|
|
135 * Hattiesburg, MS 39406-8455
|
|
136 * Internet: bgpitre@seabass.st.usm.edu
|
|
137 *
|
|
138 *
|
|
139
|
|
140 nam BAWK
|
|
141 ttl Line processing utility
|
|
142
|
|
143 ifp1
|
|
144 use defsfile
|
|
145 endc
|
|
146
|
1260
|
147 mod Size,Name,Prgrm+Objct,ReEnt+1,Start,Finish
|
0
|
148
|
|
149 Name fcs /bawk/
|
|
150 Ed fcb 3 Edition #3
|
|
151
|
|
152 Anchor rmb 1
|
|
153 Path rmb 1
|
|
154 IncFlag rmb 1 Inclusion Flag
|
|
155 FileFlag rmb 1 Show File Flag
|
|
156 ForkFlag rmb 1 Fork Shell Flag
|
|
157 FEFlag rmb 1 Fork Shell and Echo Flag
|
|
158 Delim rmb 1 Delimiter storage
|
|
159 FileBuff rmb 60 Filename buffer
|
|
160 Format rmb 250 Format buffer
|
|
161 Line rmb 250 Line buffer
|
|
162 ExpLine rmb 4096 Expanded line buffer
|
|
163 Stack rmb 200
|
|
164 Params rmb 200
|
|
165 Finish equ .
|
|
166
|
|
167
|
|
168 HelpMess fcc /Usage: BAWK [-d? -i -l -a# -f -F] "format_string" [file] [...]/
|
1564
|
169 fcb C$CR
|
0
|
170
|
|
171 Shell fcc "Shell"
|
1564
|
172 fcb C$CR
|
0
|
173
|
1564
|
174 FileHead fdb C$LF,C$CR
|
0
|
175 fcc "*** File: "
|
|
176 FileHLen equ *-FileHead
|
|
177
|
|
178 ****************************************
|
|
179 * Subroutines
|
|
180
|
|
181 ****************************************
|
|
182 * Str2Byte - Converts an ASCII string to a single byte
|
|
183 *
|
|
184 * Entry: X - Address of first char in string
|
|
185 *
|
|
186 * Exit: B - Converted byte
|
|
187 * X - Last number in string + 1
|
|
188 *
|
|
189
|
|
190 Str2Byte clrb
|
|
191 cnvloop lda ,x+
|
|
192 cmpa #'9
|
|
193 bhi cnvdone
|
|
194 suba #'0
|
|
195 blo cnvdone
|
|
196 pshs a
|
|
197 lda #10
|
|
198 mul
|
|
199 addb ,s+
|
|
200 bra cnvloop
|
|
201 cnvdone leax -1,x
|
|
202 rts
|
|
203
|
|
204 ****************************************
|
|
205 * Saves filename in buffer and print it
|
|
206 *
|
|
207 * Entry: X - Address where filename is
|
|
208 *
|
|
209 * Exit: None. File is stored in FileBuff
|
|
210 *
|
|
211
|
|
212 SaveFile pshs x
|
|
213 leay FileBuff,u
|
|
214 SaveF2 lda ,x+
|
1564
|
215 cmpa #C$SPAC
|
0
|
216 bne SaveF3
|
1564
|
217 lda #C$CR
|
0
|
218 SaveF3 sta ,y+
|
1564
|
219 cmpa #C$CR
|
0
|
220 bne SaveF2
|
|
221 puls x
|
|
222 rts
|
|
223
|
|
224 ****************************************
|
|
225 * Sets the anchor
|
|
226 *
|
|
227 * Entry: X - Address of line
|
|
228 *
|
|
229 * Exit: X - Points to the EOLN char at the
|
|
230 * end of the line
|
|
231 *
|
|
232
|
|
233 AncLine pshs b save counter
|
|
234 tst Anchor Anchor to a column other than 1 or 0?
|
|
235 beq Return Nope, process at first column
|
|
236 AncLoop ldb Anchor else move X to anchor point
|
|
237 Anc2 lda ,x+
|
1564
|
238 cmpa #C$CR
|
0
|
239 beq BackUp
|
|
240 decb
|
|
241 bne Anc2
|
|
242 BackUp leax -1,x
|
|
243 Return puls b
|
|
244 rts
|
|
245
|
|
246 ****************************************
|
|
247 * Prints filename to StdOut
|
|
248 *
|
|
249 * Entry: None
|
|
250 *
|
|
251 * Exit: None
|
|
252 *
|
|
253 * Prints a file header to StdOut along with
|
|
254 * the filename.
|
|
255 *
|
|
256
|
|
257 PrnFile pshs x
|
|
258 leax FileHead,pcr
|
|
259 lda #1
|
|
260 ldy #FileHLen
|
|
261 os9 I$Write
|
|
262 lbcs Error
|
|
263 leax FileBuff,u
|
|
264 lda #1
|
|
265 ldy #60
|
|
266 os9 I$WritLn
|
|
267 lbcs Error
|
|
268 puls x
|
|
269 rts
|
|
270
|
|
271 ****************************************
|
|
272 * Strips leading spaces
|
|
273 *
|
|
274 * Entry: X - Address of line
|
|
275 *
|
|
276 * Exit: X - Points to first non-space character
|
|
277
|
|
278 EatSpace pshs a
|
|
279 Eat2 lda ,x+
|
1564
|
280 cmpa #C$SPAC
|
0
|
281 beq Eat2
|
|
282 leax -1,x
|
|
283 puls a
|
|
284 rts
|
|
285
|
|
286 ****************************************
|
|
287 * Entry of program
|
|
288
|
|
289 Start decb any params?
|
|
290 lbeq Help nope, exit w/ error
|
|
291
|
|
292 clr Path assume stdin upon entry
|
|
293 clr IncFlag Clear (OFF) inclusion flag
|
|
294 clr FileFlag Clear printing of filenames
|
|
295 clr Anchor Anchor to first column
|
|
296 clr FEFlag Clear Fork/Echo flag
|
|
297 clr ForkFlag Clear Fork flag
|
1564
|
298 lda #C$SPAC put space as extra delimiter
|
0
|
299 sta Delim
|
|
300
|
|
301 ****************************************
|
|
302 * Command line parsing is done here
|
|
303
|
|
304 Parse bsr EatSpace
|
|
305 lda ,x+
|
1564
|
306 cmpa #C$CR
|
0
|
307 beq Help
|
|
308 cmpa #'-
|
|
309 bne IsItQ
|
|
310 * Dash options parsed here
|
|
311 lda ,x+ load A with char
|
|
312 cmpa #'a is it the anchor option?
|
|
313 bne IsItF
|
|
314 lbsr Str2Byte
|
|
315 stb Anchor
|
|
316 bra Parse
|
|
317 IsItF cmpa #'f
|
|
318 bne IsItUpF
|
|
319 lda #$ff
|
|
320 sta ForkFlag
|
|
321 bra Parse
|
|
322 IsItUpF cmpa #'F
|
|
323 bne IsItL
|
|
324 lda #$ff
|
|
325 sta FEFlag
|
|
326 bra Parse
|
|
327 IsItL cmpa #'l
|
|
328 bne IsItI
|
|
329 lda #$FF
|
|
330 sta FileFlag
|
|
331 bra Parse
|
|
332 IsItI cmpa #'i is it the inclusion option?
|
|
333 bne IsItD
|
|
334 lda #$ff set Inclusion Flag
|
|
335 sta IncFlag
|
|
336 bra Parse
|
|
337 IsItD cmpa #'d delimiter?
|
|
338 bne Help bad option -- error out
|
|
339 lda ,x+ else load character after the 'D'
|
|
340 sta Delim save it...
|
|
341 bra Parse then go back to parsing the line
|
|
342 * Format String detected here
|
|
343 IsItQ cmpa #'" Is it a '"' format string?
|
|
344 bne Help nope, must be an error
|
|
345
|
|
346 * Save the format string
|
|
347 SaveFmat leay Format,u
|
|
348 SaveFmt2 lda ,x+ Point to char after first '"'
|
1564
|
349 cmpa #C$CR
|
0
|
350 beq Help
|
|
351 cmpa #'" is it the second '"'?
|
|
352 bne SaveFmt3 no, save char
|
1564
|
353 lda #C$CR
|
0
|
354 sta ,y
|
|
355 bra ChkFile
|
|
356 SaveFmt3 sta ,y+ else save char
|
|
357 bra SaveFmt2
|
|
358 ChkFile lbsr EatSpace Check after last '"' for a filename
|
|
359 lda ,x
|
1564
|
360 cmpa #C$CR if no filename, execute from StdIn
|
0
|
361 beq MainLine
|
|
362 bra OpenFile
|
|
363
|
|
364 ****************************************
|
|
365 * Help Routine
|
|
366 *
|
|
367
|
|
368 Help leax HelpMess,pcr Show Help message
|
|
369 lda #2
|
|
370 os9 I$WritLn
|
|
371 bra Done
|
|
372
|
|
373 ****************************************
|
|
374 * Check for EOF
|
|
375 *
|
|
376
|
|
377 EOF cmpb #E$EOF
|
|
378 bne Error
|
1260
|
379 lda Path
|
0
|
380 os9 I$Close Close path
|
|
381 puls x and restore the cmd line pointer
|
|
382 tst Path
|
|
383 beq Done
|
|
384 bra FilePrs
|
|
385
|
|
386 ****************************************
|
|
387 * Exit Here
|
|
388 *
|
|
389
|
|
390 Done clrb
|
|
391 Error os9 F$Exit
|
|
392
|
|
393
|
|
394 ****************************************
|
|
395 * BAWK goes here if files are on the cmd line
|
|
396 *
|
|
397
|
|
398 FilePrs lbsr EatSpace eat spaces
|
|
399 lda ,x check char
|
1564
|
400 cmpa #C$CR if CR,
|
0
|
401 beq Done
|
|
402
|
|
403 OpenFile lbsr SaveFile
|
1260
|
404 lda #READ. else assume a file name
|
0
|
405 os9 I$Open and try to open it
|
|
406 bcs Error
|
|
407 sta Path
|
|
408 tst FileFlag
|
|
409 beq MainLine
|
|
410 lbsr PrnFile
|
|
411
|
|
412 ****************************************
|
|
413 * The following lines are the "heart" of BAWK's processing
|
|
414 *
|
|
415
|
|
416 MainLine pshs x save pointer to cmd line
|
|
417
|
|
418 ****************************************
|
|
419 * The line of input is read from here.
|
|
420 *
|
|
421
|
|
422 ReadLine lda Path get path
|
|
423 ldy #250 max chars per line
|
|
424 leax Line,u point to line buffer
|
|
425 os9 I$ReadLn and read the line
|
|
426 bcs EOF check EOF if error
|
|
427
|
|
428 ****************************************
|
|
429 * The Process of Expansion starts here.
|
|
430 *
|
|
431
|
|
432 ProcLine leax Format,u
|
|
433 leay ExpLine,u Position Y to expansion line
|
|
434
|
|
435 ParseFmt lda ,x+
|
|
436 cmpa #'$ Is it the '$' field character?
|
|
437 beq FieldPar Check Field Parameter
|
|
438 PFmt2 sta ,y+
|
1564
|
439 cmpa #C$CR
|
0
|
440 bne ParseFmt
|
|
441 tst ForkFlag
|
|
442 bne PFmt3
|
|
443 bsr Print
|
|
444 tst FEFlag see if the fork/echo flag is set
|
|
445 beq ReadLine
|
|
446 PFmt3 lbsr Fork
|
|
447 bra ReadLine
|
|
448 FieldPar lda ,x+ get char after '$'
|
|
449 cmpa #'$ Is it another?
|
|
450 beq PFmt2 yep, store it
|
|
451 leax -1,x
|
|
452 FieldP2 lbsr Str2Byte convert the number
|
|
453 tstb check the number to see if it's 0
|
|
454 bne Field1
|
|
455
|
|
456 ****************************************
|
|
457 * The entire line is copied at the direction of $0
|
|
458 *
|
|
459
|
|
460 pshs x
|
|
461 leax Line,u at this point we copy the entire...
|
|
462 lbsr AncLine Anchor the line
|
|
463 CopyAll lda ,x+ and transfer the rest of the line
|
1564
|
464 cmpa #C$CR line since we've encountered a $0
|
0
|
465 beq Field3 and continue parsing
|
|
466 sta ,y+
|
|
467 bra CopyAll
|
|
468
|
|
469 Field1 pshs x save position in format string
|
|
470 bsr SetField Position to the proper field
|
|
471 tstb was there an error?
|
|
472 beq Field2 no, continue with expansion
|
|
473 tst IncFlag is the inclusion flag set?
|
|
474 bne Field2
|
|
475 puls x
|
|
476 bra ReadLine
|
|
477 Field2 bsr Expand
|
|
478 Field3 puls x get position in format string
|
|
479 bra ParseFmt and continue expanding...
|
|
480
|
|
481
|
|
482 ****************************************
|
|
483 * SETFIELD - This routine positions the X pointer to the correct field
|
|
484 *
|
|
485 * Entry: B - Number of the field
|
|
486 *
|
|
487 * Exit: B - clear if field was found, set if it wasn't found
|
|
488 * X - Address of Bth field (Points to EOLN if B is set)
|
|
489 *
|
|
490
|
|
491 SetField leax Line,u
|
|
492 lbsr AncLine Anchor the line
|
|
493 Skip lda ,x+
|
1564
|
494 cmpa #C$SPAC
|
0
|
495 beq Skip
|
|
496 cmpa Delim
|
|
497 beq Skip
|
1564
|
498 cmpa #C$CR
|
0
|
499 beq Leave2
|
|
500 decb
|
|
501 beq Leave
|
|
502 EatField lda ,x+
|
1564
|
503 cmpa #C$SPAC
|
0
|
504 beq Skip
|
|
505 cmpa Delim
|
|
506 beq Skip
|
1564
|
507 cmpa #C$CR
|
0
|
508 beq Leave2
|
|
509 bra EatField
|
|
510 Leave clrb
|
|
511 Leave2 leax -1,x
|
1564
|
512 ExExit rts
|
0
|
513
|
|
514
|
|
515 ****************************************
|
|
516 * EXPAND - This routine "expands" the field into the expansion buffer
|
|
517 *
|
|
518
|
|
519 Expand lda ,x+
|
1564
|
520 cmpa #C$SPAC
|
0
|
521 beq ExExit
|
|
522 cmpa Delim
|
|
523 beq ExExit
|
1564
|
524 cmpa #C$CR
|
0
|
525 beq ExExit
|
|
526 sta ,y+
|
|
527 bra Expand
|
|
528
|
|
529
|
|
530 ****************************************
|
|
531 * The expanded line is printed to StdOut here
|
|
532 *
|
|
533
|
|
534 Print leax ExpLine,u Point X to the expanded line buffer
|
|
535 ldy #500 max chars 500
|
|
536 lda #1
|
|
537 os9 I$WritLn write to stdout
|
|
538 lbcs Error
|
|
539 rts
|
|
540
|
|
541 ****************************************
|
|
542 * The expanded line is used as a paramter to a shell
|
|
543 *
|
|
544
|
|
545 Fork pshs x,u
|
|
546 lda #Prgrm+Objct
|
|
547 ldb #16 Use 16 pages (4K) of data
|
|
548 leax Shell,pcr Point to name of Shell
|
|
549 ldy #4096
|
|
550 leau ExpLine,u Point X to the expanded line buffer
|
|
551 os9 F$Fork Fork it!
|
|
552 lbcs Error
|
|
553 os9 F$Wait
|
|
554 puls x,u
|
|
555 rts
|
|
556
|
|
557 emod
|
|
558 Size equ *
|
|
559 end
|
1260
|
560
|