forked from wuzhouhui/awk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
awkcode.txt
3283 lines (3282 loc) · 116 KB
/
awkcode.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# unbundle - unpack a bundle into separate files
$1 != prev { close(prev); prev = $1 }
{ print substr($0, index($0, " ") + 1) >$1 }
emp.data Beth 4.00 0
emp.data Dan 3.75 0
emp.data Kathy 4.00 10
emp.data Mark 5.00 20
emp.data Mary 5.50 22
emp.data Susie 4.25 18
05.awk { print $1, $3 }
28.awk { print NF, $1, $NF }
06.awk { print $1, $2 * $3 }
07.awk { print NR, $0 }
10.awk { print "total pay for", $1, "is", $2 * $3 }
11.awk { printf("total pay for %s is $%.2f\n", $1, $2 * $3) }
11a.awk { printf("%-8s $%6.2f\n", $1, $2 * $3) }
08.sh awk '{ printf("%6.2f %s\n", $2 * $3, $0) }' emp.data | sort
12.awk $2 >= 5
13.awk $2 * $3 > 50 { printf("$%.2f for %s\n", $2 * $3, $1) }
14.awk $1 == "Susie"
15.awk /Susie/
20.awk $2 >= 4 || $3 >= 20
21.awk $2 >= 4
21.awk $3 >= 20
22.awk !($2 < 4 && $3 < 20)
26.awk NF != 3 { print $0, "number of fields is not equal to 3" }
26.awk $2 < 3.35 { print $0, "rate is below minimum wage" }
26.awk $2 > 10 { print $0, "rate exceeds $10 per hour" }
26.awk $3 < 0 { print $0, "negative hours worked" }
26.awk $3 > 60 { print $0, "too many hours worked" }
30.awk BEGIN { print "NAME RATE HOURS"; print "" }
30.awk { print }
31.awk $3 > 15 { emp = emp + 1 }
31.awk END { print emp, "employees worked more than 15 hours" }
31a.awk END { print NR, "employees" }
32.awk { pay = pay + $2 * $3 }
32.awk END { print NR, "employees"
32.awk print "total pay is", pay
32.awk print "average pay is", pay/NR
32.awk }
33.awk $2 > maxrate { maxrate = $2; maxemp = $1 }
33.awk END { print "highest hourly rate:", maxrate, "for", maxemp }
34.awk { names = names $1 " " }
34.awk END { print names }
33a.awk { last = $0 }
33a.awk END { print last }
40.awk { print $1, length($1) }
40a.awk { nc = nc + length($0) + 1
40a.awk nw = nw + NF
40a.awk }
40a.awk END { print NR, "lines,", nw, "words,", nc, "characters" }
41.awk $2 > 6 { n = n + 1; pay = pay + $2 * $3 }
41.awk END { if (n > 0)
41.awk print n, "employees, total pay is", pay,
41.awk "average pay is", pay/n
41.awk else
41.awk print "no employees are paid more than $6/hour"
41.awk }
interest1.awk # interest1 - compute compound interest
interest1.awk # input: amount rate years
interest1.awk # output: compounded value at the end of each year
interest1.awk
interest1.awk { i = 1
interest1.awk while (i <= $3) {
interest1.awk printf("\t%.2f\n", $1 * (1 + $2) ^ i)
interest1.awk i = i + 1
interest1.awk }
interest1.awk }
forint.awk # interest2 - compute compound interest
forint.awk # input: amount rate years
forint.awk # output: compounded value at the end of each year
forint.awk
forint.awk { for (i = 1; i <= $3; i = i + 1)
forint.awk printf("\t%.2f\n", $1 * (1 + $2) ^ i)
forint.awk }
50.awk # reverse - print input in reverse order by line
50.awk
50.awk { line[NR] = $0 } # remember each input line
50.awk
50.awk END { i = NR # print lines in reverse order
50.awk while (i > 0) {
50.awk print line[i]
50.awk i = i - 1
50.awk }
50.awk }
51.awk # reverse - print input in reverse order by line
51.awk
51.awk { line[NR] = $0 } # remember each input line
51.awk
51.awk END { for (i = NR; i > 0; i = i - 1)
51.awk print line[i]
51.awk }
61.awk END { print NR }
62.awk NR == 10
66.awk { print $NF }
63.awk { field = $NF}
63.awk END { print field }
64.awk NF > 4
65.awk $NF > 4
67.awk { nf = nf + NF }
67.awk END { print nf }
68.awk /Beth/ { nlines = nlines + 1 }
68.awk END { print nlines }
69.awk $1 > max { max = $1; maxline = $0 }
69.awk END { print max, maxline }
70.awk NF > 0
71.awk length($0) > 80
72.awk { print NF, $0 }
73.awk { print $2, $1 }
74.awk { temp = $1; $1 = $2; $2 = temp; print }
75.awk { $1 = NR; print }
76.awk { $2 = ""; print }
77.awk { for (i = NF; i > 0; i = i - 1) printf("%s ", $i)
77.awk printf("\n")
77.awk }
78.awk { sum = 0
78.awk for (i = 1; i <= NF; i = i + 1) sum = sum + $i
78.awk print sum
78.awk }
79.awk { for (i = 1; i <= NF; i = i + 1) sum = sum + $i }
79.awk END { print sum }
80.awk { for (i = 1; i <= NF; i = i + 1) if ($i < 0) $i = -$i
80.awk print
80.awk }
countries USSR 8649 275 Asia
countries Canada 3852 25 North America
countries China 3705 1032 Asia
countries USA 3615 237 North America
countries Brazil 3286 134 South America
countries India 1267 746 Asia
countries Mexico 762 78 North America
countries France 211 55 Europe
countries Japan 144 120 Asia
countries Germany 96 61 Europe
countries England 94 56 Europe
p11.awk # print countries with column headers and totals
p11.awk
p11.awk BEGIN { FS = "\t" # make tab the field separator
p11.awk printf("%10s %6s %5s %s\n\n",
p11.awk "COUNTRY", "AREA", "POP", "CONTINENT")
p11.awk }
p11.awk { printf("%10s %6d %5d %s\n", $1, $2, $3, $4)
p11.awk area = area + $2
p11.awk pop = pop + $3
p11.awk }
p11.awk END { printf("\n%10s %6d %5d\n", "TOTAL", area, pop) }
p12.awk $0 >= "M"
p13.awk $1 < $4
p13a.awk /Asia/
re1.awk /^[0-9]+$/
re2.awk /^[0-9][0-9][0-9]$/
re3.awk /^(\+|-)?[0-9]+\.?[0-9]*$/
re4.awk /^[+-]?[0-9]+[.]?[0-9]*$/
re5.awk /^[+-]?([0-9]+[.]?[0-9]*|[.][0-9]+)([eE][+-]?[0-9]+)?$/
re6.awk /^[A-Za-z][A-Za-z0-9]*$/
re7.awk /^[A-Za-z]$|^[A-Za-z][0-9]$/
re8.awk /^[A-Za-z][0-9]?$/
p16.awk $2 !~ /^[0-9]+$/
p18.awk $4 == "Asia" && $3 > 500
p19.awk $4 == "Asia" || $4 == "Europe"
p20.awk $4 ~ /^(Asia|Europe)$/
p20a.awk /Asia/ || /Europe/
p20b.awk /Asia|Europe/
p21.awk /Europe/, /Africa/
p22.awk FNR == 1, FNR == 5 { print FILENAME ": " $0 }
p22a.awk FNR <= 5 { print FILENAME ": " $0 }
p23.awk $4 == "Asia" { print $1, 1000 * $2 }
p41.awk { $2 = $2 / 1000; print }
p42.awk BEGIN { FS = OFS = "\t" }
p42.awk $4 == "North America" { $4 = "NA" }
p42.awk $4 == "South America" { $4 = "SA" }
p42.awk { print }
p43.awk BEGIN { FS = OFS = "\t" }
p43.awk { $5 = 1000 * $3 / $2; print }
p43a.awk { print ($1 != 0 ? 1/$1 : "$1 is zero, line " NR) }
p32.awk $4 == "Asia" { pop = pop + $3; n = n + 1 }
p32.awk END { print "Total population of the", n,
p32.awk "Asian countries is", pop, "million."
p32.awk }
p34.awk $3 > maxpop { maxpop = $3; country = $1 }
p34.awk END { print "country with largest population:",
p34.awk country, maxpop
p34.awk }
p24.awk { $2 /= 1000; print }
p35.awk { print NR ":" $0 }
p17.awk BEGIN { digits = "^[0-9]+$" }
p17.awk $2 ~ digits
builtup.awk BEGIN {
builtup.awk sign = "[+-]?"
builtup.awk decimal = "[0-9]+[.]?[0-9]*"
builtup.awk fraction = "[.][0-9]+"
builtup.awk exponent = "([eE]" sign "[0-9]+)?"
builtup.awk number = "^" sign "(" decimal "|" fraction ")" exponent "$"
builtup.awk }
builtup.awk $0 ~ number
p36.awk { gsub(/USA/, "United States"); print }
p39.awk { $1 = substr($1, 1, 3); print $0 }
p40.awk { s = s substr($1, 1, 3) " " }
p40.awk END { print s }
p40a.awk BEGIN { print "1E2"+0, "12E"+0, "E12"+0, "1X2Y3"+0 }
p40b.awk BEGIN { print 1E2 "", 12E-2 "", E12 "", 1.23456789 "" }
p45.awk { i = 1
p45.awk while (i <= NF) {
p45.awk print $i
p45.awk i++
p45.awk }
p45.awk }
p46.awk { for (i = 1; i <= NF; i++)
p46.awk print $i
p46.awk }
empty.awk BEGIN { FS = "\t" }
empty.awk { for (i = 1; i <= NF && $i != ""; i++)
empty.awk ;
empty.awk if (i <= NF)
empty.awk print
empty.awk }
revline.awk { x[NR] = $0 }
revline.awk END { for (i = NR; i > 0; i--) print x[i] }
p47.awk /Asia/ { pop["Asia"] += $3 }
p47.awk /Europe/ { pop["Europe"] += $3 }
p47.awk END { print "Asian population is",
p47.awk pop["Asia"], "million."
p47.awk print "European population is",
p47.awk pop["Europe"], "million."
p47.awk }
p48.awk BEGIN { FS = "\t" }
p48.awk { pop[$4] += $3 }
p48.awk END { for (name in pop)
p48.awk print name, pop[name]
p48.awk }
p51.awk function max(m, n) {
p51.awk return m > n ? m : n
p51.awk }
p51a.awk { print max($1,max($2,$3)) } # print maximum of $1, $2, $3
p51a.awk
p51a.awk function max(m, n) {
p51a.awk return m > n ? m : n
p51a.awk }
p52.awk BEGIN { OFS = ":"; ORS = "\n\n" }
p52.awk { print $1, $2 }
p53.awk $3 > 100 { print $1, $3 >"bigpop" }
p53.awk $3 <= 100 { print $1, $3 >"smallpop" }
p53a.awk { print($1, $3) > ($3 > 100 ? "bigpop" : "smallpop") }
p53b.awk { print > $1 }
p54.awk # print continents and populations, sorted by population
p54.awk
p54.awk BEGIN { FS = "\t" }
p54.awk { pop[$4] += $3 }
p54.awk END { for (c in pop)
p54.awk printf("%15s\t%6d\n", c, pop[c]) | "sort -t'\t' +1rn"
p54.awk }
p60.awk # include - replace #include "f" by contents of file f
p60.awk
p60.awk /^#include/ {
p60.awk gsub(/"/, "", $2)
p60.awk while (getline x <$2 > 0)
p60.awk print x
p60.awk next
p60.awk }
p60.awk { print }
p61.awk # echo - print command-line arguments
p61.awk
p61.awk BEGIN {
p61.awk for (i = 1; i < ARGC; i++)
p61.awk printf "%s ", ARGV[i]
p61.awk printf "\n"
p61.awk }
p44.awk # seq - print sequences of integers
p44.awk # input: arguments q, p q, or p q r; q >= p; r > 0
p44.awk # output: integers 1 to q, p to q, or p to q in steps of r
p44.awk
p44.awk BEGIN {
p44.awk if (ARGC == 2)
p44.awk for (i = 1; i <= ARGV[1]; i++)
p44.awk print i
p44.awk else if (ARGC == 3)
p44.awk for (i = ARGV[1]; i <= ARGV[2]; i++)
p44.awk print i
p44.awk else if (ARGC == 4)
p44.awk for (i = ARGV[1]; i <= ARGV[2]; i += ARGV[3])
p44.awk print i
p44.awk }
p62.awk $1 == "#include" { gsub(/"/, "", $2); system("cat " $2); next }
p62.awk { print }
field.awk # field - print named fields of each input line
field.awk # usage: field n n n ... file file file ...
field.awk
field.awk awk '
field.awk BEGIN {
field.awk for (i = 1; ARGV[i] ~ /^[0-9]+$/; i++) { # collect numbers
field.awk fld[++nf] = ARGV[i]
field.awk ARGV[i] = ""
field.awk }
field.awk if (i >= ARGC) # no file names so force stdin
field.awk ARGV[ARGC++] = "-"
field.awk }
field.awk { for (i = 1; i <= nf; i++)
field.awk printf("%s%s", $fld[i], i < nf ? " " : "\n")
field.awk }
field.awk ' $*
sum1 # sum1 - print column sums
sum1 # input: rows of numbers
sum1 # output: sum of each column
sum1 # missing entries are treated as zeros
sum1
sum1 { for (i = 1; i <= NF; i++)
sum1 sum[i] += $i
sum1 if (NF > maxfld)
sum1 maxfld = NF
sum1 }
sum1 END { for (i = 1; i <= maxfld; i++) {
sum1 printf("%g", sum[i])
sum1 if (i < maxfld)
sum1 printf("\t")
sum1 else
sum1 printf("\n")
sum1 }
sum1 }
sum2 # sum2 - print column sums
sum2 # check that each line has the same number of fields
sum2 # as line one
sum2
sum2 NR==1 { nfld = NF }
sum2 { for (i = 1; i <= NF; i++)
sum2 sum[i] += $i
sum2 if (NF != nfld)
sum2 print "line " NR " has " NF " entries, not " nfld
sum2 }
sum2 END { for (i = 1; i <= nfld; i++)
sum2 printf("%g%s", sum[i], i < nfld ? "\t" : "\n")
sum2 }
sum3 # sum3 - print sums of numeric columns
sum3 # input: rows of integers and strings
sum3 # output: sums of numeric columns
sum3 # assumes every line has same layout
sum3
sum3 NR==1 { nfld = NF
sum3 for (i = 1; i <= NF; i++)
sum3 numcol[i] = isnum($i)
sum3 }
sum3
sum3 { for (i = 1; i <= NF; i++)
sum3 if (numcol[i])
sum3 sum[i] += $i
sum3 }
sum3
sum3 END { for (i = 1; i <= nfld; i++) {
sum3 if (numcol[i])
sum3 printf("%g", sum[i])
sum3 else
sum3 printf("--")
sum3 printf(i < nfld ? "\t" : "\n")
sum3 }
sum3 }
sum3
sum3 function isnum(n) { return n ~ /^[+-]?[0-9]+$/ }
3-4.ans { total[$1] += $2 }
3-4.ans END { for (x in total) print x, total[x] | "sort" }
percent # percent
percent # input: a column of nonnegative numbers
percent # output: each number and its percentage of the total
percent
percent { x[NR] = $1; sum += $1 }
percent
percent END { if (sum != 0)
percent for (i = 1; i <= NR; i++)
percent printf("%10.2f %5.1f\n", x[i], 100*x[i]/sum)
percent }
histogram # histogram
histogram # input: numbers between 0 and 100
histogram # output: histogram of deciles
histogram
histogram { x[int($1/10)]++ }
histogram
histogram END { for (i = 0; i < 10; i++)
histogram printf(" %2d - %2d: %3d %s\n",
histogram 10*i, 10*i+9, x[i], rep(x[i],"*"))
histogram printf("100: %3d %s\n", x[10], rep(x[10],"*"))
histogram }
histogram
histogram function rep(n,s, t) { # return string of n s's
histogram while (n-- > 0)
histogram t = t s
histogram return t
histogram }
hist.sh awk '
hist.sh # generate random integers
hist.sh BEGIN { for (i = 1; i <= 200; i++)
hist.sh print int(101*rand())
hist.sh }
hist.sh ' |
hist.sh awk -f histogram
histans1.awk
histans1.awk { x[int($1/10)]++ }
histans1.awk END { max = MAXSTARS = 25
histans1.awk for (i = 0; i <= 10; i++)
histans1.awk if (x[i] > max)
histans1.awk max = x[i]
histans1.awk for (i = 0; i <= 10; i++)
histans1.awk y[i] = x[i]/max * MAXSTARS
histans1.awk for (i = 0; i < 10; i++)
histans1.awk printf(" %2d - %2d: %3d %s\n",
histans1.awk 10*i, 10*i+9, x[i], rep(y[i],"*"))
histans1.awk printf("100: %3d %s\n", x[10], rep(y[10],"*"))
histans1.awk }
histans1.awk
histans1.awk function rep(n,s, t) { # return string of n s's
histans1.awk while (n-- > 0)
histans1.awk t = t s
histans1.awk return t
histans1.awk }
sumcomma # sumcomma - add up numbers containing commas
sumcomma
sumcomma { gsub(/,/, ""); sum += $0 }
sumcomma END { print sum }
addcomma # addcomma - put commas in numbers
addcomma # input: a number per line
addcomma # output: the input number followed by
addcomma # the number with commas and two decimal places
addcomma
addcomma { printf("%-12s %20s\n", $0, addcomma($0)) }
addcomma
addcomma function addcomma(x, num) {
addcomma if (x < 0)
addcomma return "-" addcomma(-x)
addcomma num = sprintf("%.2f", x) # num is dddddd.dd
addcomma while (num ~ /[0-9][0-9][0-9][0-9]/)
addcomma sub(/[0-9][0-9][0-9][,.]/, ",&", num)
addcomma return num
addcomma }
addcomma.ans /^[+-]?[0-9][0-9]?[0-9]?(,[0-9][0-9][0-9])*$/ {
addcomma.ans gsub(/,/, "")
addcomma.ans sum += $0
addcomma.ans next
addcomma.ans }
addcomma.ans { print "bad format:", $0 }
addcomma.ans END { print sum }
addcomma.ans2 /^[+-]?[0-9][0-9]?[0-9]?(,[0-9][0-9][0-9])*([.][0-9]*)?$/ {
addcomma.ans2 gsub(/,/, "")
addcomma.ans2 sum += $0
addcomma.ans2 next
addcomma.ans2 }
addcomma.ans2 { print "bad format:", $0}
addcomma.ans2 END { print sum }
datecvt # date convert - convert mmddyy into yymmdd in $1
datecvt
datecvt { $1 = substr($1,5,2) substr($1,1,2) substr($1,3,2); print }
date.data 013042 mary's birthday
date.data 032772 mark's birthday
date.data 052470 anniversary
date.data 061209 mother's birthday
date.data 110175 elizabeth's birthday
daynum function daynum(y, m, d, days, i, n) { # 1 == Jan 1, 1901
daynum split("31 28 31 30 31 30 31 31 30 31 30 31", days)
daynum # 365 days a year, plus one for each leap year
daynum n = (y-1901) * 365 + int((y-1901)/4)
daynum if (y % 4 == 0) # leap year from 1901 to 2099
daynum days[2]++
daynum for (i = 1; i < m; i++)
daynum n += days[i]
daynum return n + d
daynum }
daynum { print daynum($1, $2, $3) }
nm.output file.o:
nm.output 00000c80 T _addroot
nm.output 00000b30 T _checkdev
nm.output 00000a3c T _checkdupl
nm.output U _chown
nm.output U _client
nm.output U _close
nm.output funmount.o:
nm.output 00000000 T _funmount
nm.output U cerror
nm.format # nm.format - add filename to each nm output line
nm.format
nm.format NF == 1 { file = $1 }
nm.format NF == 2 { print file, $1, $2 }
nm.format NF == 3 { print file, $2, $3 }
prchecks # prchecks - print formatted checks
prchecks # input: number \t amount \t payee
prchecks # output: eight lines of text for preprinted check forms
prchecks
prchecks BEGIN {
prchecks FS = "\t"
prchecks dashes = sp45 = sprintf("%45s", " ")
prchecks gsub(/ /, "-", dashes) # to protect the payee
prchecks "date" | getline date # get today's date
prchecks split(date, d, " ")
prchecks date = d[2] " " d[3] ", " d[6]
prchecks initnum() # set up tables for number conversion
prchecks }
prchecks NF != 3 || $2 >= 1000000 { # illegal data
prchecks printf("\nline %d illegal:\n%s\n\nVOID\nVOID\n\n\n", NR, $0)
prchecks next # no check printed
prchecks }
prchecks { printf("\n") # nothing on line 1
prchecks printf("%s%s\n", sp45, $1) # number, indented 45 spaces
prchecks printf("%s%s\n", sp45, date) # date, indented 45 spaces
prchecks amt = sprintf("%.2f", $2) # formatted amount
prchecks printf("Pay to %45.45s $%s\n", $3 dashes, amt) # line 4
prchecks printf("the sum of %s\n", numtowords(amt)) # line 5
prchecks printf("\n\n\n") # lines 6, 7 and 8
prchecks }
prchecks
prchecks function numtowords(n, cents, dols) { # n has 2 decimal places
prchecks cents = substr(n, length(n)-1, 2)
prchecks dols = substr(n, 1, length(n)-3)
prchecks if (dols == 0)
prchecks return "zero dollars and " cents " cents exactly"
prchecks return intowords(dols) " dollars and " cents " cents exactly"
prchecks }
prchecks
prchecks function intowords(n) {
prchecks n = int(n)
prchecks if (n >= 1000)
prchecks return intowords(n/1000) " thousand " intowords(n%1000)
prchecks if (n >= 100)
prchecks return intowords(n/100) " hundred " intowords(n%100)
prchecks if (n >= 20)
prchecks return tens[int(n/10)] " " intowords(n%10)
prchecks return nums[n]
prchecks }
prchecks
prchecks function initnum() {
prchecks split("one two three four five six seven eight nine " \
prchecks "ten eleven twelve thirteen fourteen fifteen " \
prchecks "sixteen seventeen eighteen nineteen", nums, " ")
prchecks split("ten twenty thirty forty fifty sixty " \
prchecks "seventy eighty ninety", tens, " ")
prchecks }
checkfix.ans # prchecks - print formatted checks
checkfix.ans # input: number \t amount \t payee
checkfix.ans # output: eight lines of text for preprinted check forms
checkfix.ans
checkfix.ans BEGIN {
checkfix.ans FS = "\t"
checkfix.ans dashes = sp45 = sprintf("%45s", " ")
checkfix.ans gsub(/ /, "-", dashes) # to protect the payee
checkfix.ans "date" | getline date # get today's date
checkfix.ans split(date, d, " ")
checkfix.ans date = d[2] ". " d[3] ", " d[6]
checkfix.ans initnum() # set up tables for number conversion
checkfix.ans }
checkfix.ans NF != 3 {
checkfix.ans printf("\nrec %d has %d fields:\n|%s|\n\nVOID\nVOID\n\n\n",
checkfix.ans NR, NF, $0)
checkfix.ans next
checkfix.ans }
checkfix.ans { printf("\n") # nothing on line 1
checkfix.ans printf("%s%s\n", sp45, $1) # number, indented 45 spaces
checkfix.ans printf("%s%s\n", sp45, date) # date, indented 45 spaces
checkfix.ans amt = sprintf("%.2f", $2) # formatted amount
checkfix.ans printf("Pay to %45.45s $%s\n", $3 dashes, amt) # line 4
checkfix.ans printf("the sum of %s\n", numtowords(amt)) # line 5
checkfix.ans printf("\n\n\n") # lines 6, 7 and 8
checkfix.ans }
checkfix.ans function numtowords(n, cents, dols, s) { # n has 2 decimal places
checkfix.ans cents = substr(n, length(n)-1, 2)
checkfix.ans dols = substr(n, 1, length(n)-3)
checkfix.ans if (dols == 0)
checkfix.ans s = "zero dollars and " cents " cents exactly"
checkfix.ans else
checkfix.ans s = intowords(dols) " dollars and " cents " cents exactly"
checkfix.ans sub(/^one dollars/, "one dollar", s)
checkfix.ans gsub(/ +/, " ", s)
checkfix.ans return s
checkfix.ans }
checkfix.ans function intowords(n) {
checkfix.ans n = int(n)
checkfix.ans if (n >= 1000000)
checkfix.ans return("VOID")
checkfix.ans if (n >= 1000)
checkfix.ans return intowords(n/1000) " thousand " intowords(n%1000)
checkfix.ans if (n >= 100)
checkfix.ans return intowords(n/100) " hundred " intowords(n%100)
checkfix.ans if (n >= 20)
checkfix.ans return tens[int(n/10)] " " intowords(n%10)
checkfix.ans return nums[n]
checkfix.ans }
checkfix.ans function initnum() {
checkfix.ans split("one two three four five six seven eight nine " \
checkfix.ans "ten eleven twelve thirteen fourteen fifteen " \
checkfix.ans "sixteen seventeen eighteen nineteen", nums, " ")
checkfix.ans split("ten twenty thirty forty fifty sixty " \
checkfix.ans "seventy eighty ninety", tens, " ")
checkfix.ans }
colcheck # colcheck - check consistency of columns
colcheck # input: rows of numbers and strings
colcheck # output: lines whose format differs from first line
colcheck
colcheck NR == 1 {
colcheck nfld = NF
colcheck for (i = 1; i <= NF; i++)
colcheck type[i] = isnum($i)
colcheck }
colcheck { if (NF != nfld)
colcheck printf("line %d has %d fields instead of %d\n",
colcheck NR, NF, nfld)
colcheck for (i = 1; i <= NF; i++)
colcheck if (isnum($i) != type[i])
colcheck printf("field %d in line %d differs from line 1\n",
colcheck i, NR)
colcheck }
colcheck
colcheck function isnum(n) { return n ~ /^[+-]?[0-9]+$/ }
p12check # p12check - check input for alternating .P1/.P2 delimiters
p12check
p12check /^\.P1/ { if (p != 0)
p12check print ".P1 after .P1, line", NR
p12check p = 1
p12check }
p12check /^\.P2/ { if (p != 1)
p12check print ".P2 with no preceding .P1, line", NR
p12check p = 0
p12check }
p12check END { if (p != 0) print "missing .P2 at end" }
delim.ans BEGIN {
delim.ans expects["aa"] = "bb"
delim.ans expects["cc"] = "dd"
delim.ans expects["ee"] = "ff"
delim.ans }
delim.ans /^(aa|cc|ee)/ {
delim.ans if (p != "")
delim.ans print "line", NR, ": expected " p
delim.ans p = expects[substr($0, 1, 2)]
delim.ans }
delim.ans /^(bb|dd|ff)/ {
delim.ans x = substr($0, 1, 2)
delim.ans if (p != x) {
delim.ans print "line", NR, ": saw " x
delim.ans if (p)
delim.ans print ", expected", p
delim.ans }
delim.ans p = ""
delim.ans }
delim.ans END {
delim.ans if (p != "")
delim.ans print "at end, missing", p
delim.ans }
passwd # passwd - check password file
passwd
passwd BEGIN {
passwd FS = ":" }
passwd NF != 7 {
passwd printf("line %d, does not have 7 fields: %s\n", NR, $0) }
passwd $1 ~ /[^A-Za-z0-9]/ {
passwd printf("line %d, nonalphanumeric user id: %s\n", NR, $0) }
passwd $2 == "" {
passwd printf("line %d, no password: %s\n", NR, $0) }
passwd $3 ~ /[^0-9]/ {
passwd printf("line %d, nonnumeric user id: %s\n", NR, $0) }
passwd $4 ~ /[^0-9]/ {
passwd printf("line %d, nonnumeric group id: %s\n", NR, $0) }
passwd $6 !~ /^\// {
passwd printf("line %d, invalid login directory: %s\n", NR, $0) }
checkgen.data NF != 7 does not have 7 fields
checkgen.data $1 ~ /[^A-Za-z0-9]/ nonalphanumeric user id
checkgen.data $2 == "" no password
checkgen # checkgen - generate data-checking program
checkgen # input: expressions of the form: pattern tabs message
checkgen # output: program to print message when pattern matches
checkgen
checkgen BEGIN { FS = "\t+" }
checkgen { printf("%s {\n\tprintf(\"line %%d, %s: %%s\\n\",NR,$0) }\n",
checkgen $1, $2)
checkgen }
valid.ans BEGIN { FS = "\t" }
valid.ans /^=/ { print substr($0, 2); next }
valid.ans { printf("%s {\n\tprintf(\"line %%d, %s: %%s\\n\",NR,$0) }\n",
valid.ans $1, $2)
valid.ans }
compat # compat - check if awk program uses new built-in names
compat
compat BEGIN { asplit("close system atan2 sin cos rand srand " \
compat "match sub gsub", fcns)
compat asplit("ARGC ARGV FNR RSTART RLENGTH SUBSEP", vars)
compat asplit("do delete function return", keys)
compat }
compat
compat { line = $0 }
compat
compat /"/ { gsub(/"([^"]|\\")*"/, "", line) } # remove strings,
compat /\// { gsub(/\/([^\/]|\\\/)+\//, "", line) } # reg exprs,
compat /#/ { sub(/#.*/, "", line) } # and comments
compat
compat { n = split(line, x, "[^A-Za-z0-9_]+") # into words
compat for (i = 1; i <= n; i++) {
compat if (x[i] in fcns)
compat warn(x[i] " is now a built-in function")
compat if (x[i] in vars)
compat warn(x[i] " is now a built-in variable")
compat if (x[i] in keys)
compat warn(x[i] " is now a keyword")
compat }
compat }
compat
compat function asplit(str, arr) { # make an assoc array from str
compat n = split(str, temp)
compat for (i = 1; i <= n; i++)
compat arr[temp[i]]++
compat return n
compat }
compat
compat function warn(s) {
compat sub(/^[ \t]*/, "")
compat printf("file %s, line %d: %s\n\t%s\n", FILENAME, FNR, s, $0)
compat }
bundle # bundle - combine multiple files into one
bundle
bundle { print FILENAME, $0 }
unbundle # unbundle - unpack a bundle into separate files
unbundle
unbundle $1 != prev { close(prev); prev = $1 }
unbundle { print substr($0, index($0, " ") + 1) >$1 }
addr.1 Adam Smith
addr.1 1234 Wall St., Apt. 5C
addr.1 New York, NY 10021
addr.1 212 555-4321
addr.1
addr.1 David W. Copperfield
addr.1 221 Dickens Lane
addr.1 Monterey, CA 93940
addr.1 408 555-0041
addr.1 work phone 408 555-6532
addr.1 Mary, birthday January 30
addr.1
addr.1 Canadian Consulate
addr.1 555 Fifth Ave
addr.1 New York, NY
addr.1 212 586-2400
ny1.awk BEGIN { RS = "" }
ny1.awk /New York/
ny2.awk BEGIN { RS = ""; ORS = "\n\n" }
ny2.awk /New York/
smith.awk BEGIN { RS = ""; FS = "\n" }
smith.awk $1 ~ /Smith$/ { print $1, $4 } # name, phone
msort.sh # pipeline to sort address list by last names
msort.sh
msort.sh awk '
msort.sh BEGIN { RS = ""; FS = "\n" }
msort.sh { printf("%s!!#", x[split($1, x, " ")])
msort.sh for (i = 1; i <= NF; i++)
msort.sh printf("%s%s", $i, i < NF ? "!!#" : "\n")
msort.sh }
msort.sh ' |
msort.sh sort |
msort.sh awk '
msort.sh BEGIN { FS = "!!#" }
msort.sh { for (i = 2; i <= NF; i++)
msort.sh printf("%s\n", $i)
msort.sh printf("\n")
msort.sh }
msort.sh '
addr.2 accountant
addr.2 Adam Smith
addr.2 1234 Wall St., Apt. 5C
addr.2 New York, NY 10021
addr.2
addr.2 doctor - ophthalmologist
addr.2 Dr. Will Seymour
addr.2 798 Maple Blvd.
addr.2 Berkeley Heights, NJ 07922
addr.2
addr.2 lawyer
addr.2 David W. Copperfield
addr.2 221 Dickens Lane
addr.2 Monterey, CA 93940
addr.2
addr.2 doctor - pediatrician
addr.2 Dr. Susan Mark
addr.2 600 Mountain Avenue
addr.2 Murray Hill, NJ 07974
doctors1.awk /^doctor/, /^$/
doctors2.awk /^doctor/ { p = 1; next }
doctors2.awk p == 1
doctors2.awk /^$/ { p = 0; next }
checks.data check 1021
checks.data to Champagne Unlimited
checks.data amount 123.10
checks.data date 1/1/87
checks.data
checks.data deposit
checks.data amount 500.00
checks.data date 1/1/87
checks.data
checks.data check 1022
checks.data date 1/2/87
checks.data amount 45.10
checks.data to Getwell Drug Store
checks.data tax medical
checks.data
checks.data check 1023
checks.data amount 125.00
checks.data to International Travel
checks.data date 1/3/87
checks.data
checks.data amount 50.00
checks.data to Carnegie Hall
checks.data date 1/3/87
checks.data check 1024
checks.data tax charitable contribution
checks.data
checks.data to American Express
checks.data check 1025
checks.data amount 75.75
checks.data date 1/5/87
check1 # check1 - print total deposits and checks
check1
check1 /^check/ { ck = 1; next }
check1 /^deposit/ { dep = 1; next }
check1 /^amount/ { amt = $2; next }
check1 /^$/ { addup() }
check1
check1 END { addup()
check1 printf("deposits $%.2f, checks $%.2f\n",
check1 deposits, checks)
check1 }
check1
check1 function addup() {
check1 if (ck)
check1 checks += amt
check1 else if (dep)
check1 deposits += amt
check1 ck = dep = amt = 0
check1 }
check2 # check2 - print total deposits and checks
check2
check2 BEGIN { RS = ""; FS = "\n" }
check2 /(^|\n)deposit/ { deposits += field("amount"); next }
check2 /(^|\n)check/ { checks += field("amount"); next }
check2 END { printf("deposits $%.2f, checks $%.2f\n",
check2 deposits, checks)
check2 }
check2
check2 function field(name, i,f) {
check2 for (i = 1; i <= NF; i++) {
check2 split($i, f, "\t")
check2 if (f[1] == name)
check2 return f[2]
check2 }
check2 printf("error: no field %s in record\n%s\n", name, $0)
check2 }
check3 # check3 - print check information
check3
check3 BEGIN { RS = ""; FS = "\n" }
check3 /(^|\n)check/ {
check3 for (i = 1; i <= NF; i++) {
check3 split($i, f, "\t")
check3 val[f[1]] = f[2]
check3 }
check3 printf("%8s %5d %8s %s\n",
check3 val["date"],
check3 val["check"],
check3 sprintf("$%.2f", val["amount"]),
check3 val["to"])
check3 for (i in val)
check3 delete val[i]
check3 }
prep1 # prep1 - prepare countries by continent and pop. den.
prep1
prep1 BEGIN { FS = "\t" }
prep1 { printf("%s:%s:%d:%d:%.1f\n",
prep1 $4, $1, $3, $2, 1000*$3/$2) | "sort -t: +0 -1 +4rn"
prep1 }
form1 # form1 - format countries data by continent, pop. den.
form1
form1 BEGIN { FS = ":"
form1 printf("%-15s %-10s %10s %7s %12s\n",
form1 "CONTINENT", "COUNTRY", "POPULATION",
form1 "AREA", "POP. DEN.")
form1 }
form1 { printf("%-15s %-10s %7d %10d %10.1f\n",
form1 $1, $2, $3, $4, $5)
form1 }
prep2 # prep2 - prepare countries by continent, inverse pop. den.
prep2
prep2 BEGIN { FS = "\t"}
prep2 { den = 1000*$3/$2
prep2 printf("%-15s:%12.8f:%s:%d:%d:%.1f\n",
prep2 $4, 1/den, $1, $3, $2, den) | "sort"
prep2 }
form2 # form2 - format countries by continent, pop. den.
form2
form2 BEGIN { FS = ":"
form2 printf("%-15s %-10s %10s %7s %12s\n",
form2 "CONTINENT", "COUNTRY", "POPULATION",
form2 "AREA", "POP. DEN.")
form2 }
form2 { if ($1 != prev) {
form2 print ""
form2 prev = $1
form2 } else
form2 $1 = ""
form2 printf("%-15s %-10s %7d %10d %10.1f\n",
form2 $1, $2, $3, $4, $5)
form2 }
prep3 # prep3 - prepare countries data for form3
prep3
prep3 BEGIN { FS = "\t" }
prep3 pass == 1 {
prep3 area[$4] += $2
prep3 areatot += $2
prep3 pop[$4] += $3
prep3 poptot += $3
prep3 }
prep3 pass == 2 {
prep3 den = 1000*$3/$2
prep3 printf("%s:%s:%s:%f:%d:%f:%f:%d:%d\n",
prep3 $4, $1, $3, 100*$3/poptot, $2, 100*$2/areatot,
prep3 den, pop[$4], area[$4]) | "sort -t: +0 -1 +6rn"
prep3 }
form3 # form3 - format countries report number 3
form3
form3 BEGIN {
form3 FS = ":"; date = "January 1, 1988"
form3 hfmt = "%36s %8s %12s %7s %12s\n"
form3 tfmt = "%33s %10s %10s %9s\n"
form3 TOTfmt = " TOTAL for %-13s%7d%11.1f%11d%10.1f\n"
form3 printf("%-18s %-40s %19s\n\n", "Report No. 3",
form3 "POPULATION, AREA, POPULATION DENSITY", date)
form3 printf(" %-14s %-14s %-23s %-14s %-11s\n\n",
form3 "CONTINENT", "COUNTRY", "POPULATION", "AREA", "POP. DEN.")
form3 printf(hfmt, "Millions ", "Pct. of", "Thousands ",
form3 "Pct. of", "People per")
form3 printf(hfmt, "of People", "Total ", "of Sq. Mi.",
form3 "Total ", "Sq. Mi. ")
form3 printf(hfmt, "---------", "-------", "----------",
form3 "-------", "----------")
form3 }
form3 { if ($1 != prev) { # new continent
form3 if (NR > 1)
form3 totalprint()
form3 prev = $1 # first entry for continent
form3 poptot = $8; poppct = $4
form3 areatot = $9; areapct = $6
form3 } else { # next entry for continent
form3 $1 = ""
form3 poppct += $4; areapct += $6
form3 }
form3 printf(" %-15s%-10s %6d %10.1f %10d %9.1f %10.1f\n",
form3 $1, $2, $3, $4, $5, $6, $7)
form3 gpop += $3; gpoppct += $4
form3 garea += $5; gareapct += $6
form3 }
form3
form3 END {
form3 totalprint()
form3 printf(" GRAND TOTAL %20d %10.1f %10d %9.1f\n",
form3 gpop, gpoppct, garea, gareapct)
form3 printf(tfmt, "=====", "======", "=====", "======")
form3 }
form3
form3 function totalprint() { # print totals for previous continent
form3 printf(tfmt, "----", "-----", "-----", "-----")
form3 printf(TOTfmt, prev, poptot, poppct, areatot, areapct)
form3 printf(tfmt, "====", "=====", "=====", "=====")
form3 }
form4 # form4 - format countries data for tbl input
form4
form4 BEGIN {
form4 FS = ":"; OFS = "\t"; date = "January 1, 1988"
form4 print ".TS\ncenter;"
form4 print "l c s s s r s\nl\nl l c s c s c\nl l c c c c c."
form4 printf("%s\t%s\t%s\n\n", "Report No. 3",
form4 "POPULATION, AREA, POPULATION DENSITY", date)
form4 print "CONTINENT", "COUNTRY", "POPULATION",
form4 "AREA", "POP. DEN."
form4 print "", "", "Millions", "Pct. of", "Thousands",
form4 "Pct. of", "People per"
form4 print "", "", "of People", "Total", "of Sq. Mi.",
form4 "Total", "Sq. Mi."
form4 print "\t\t_\t_\t_\t_\t_"
form4 print ".T&\nl l n n n n n."
form4 }
form4
form4 { if ($1 != prev) { # new continent
form4 if (NR > 1)
form4 totalprint()
form4 prev = $1
form4 poptot = $8; poppct = $4
form4 areatot = $9; areapct = $6
form4 } else { # next entry for current continent
form4 $1 = ""
form4 poppct += $4; areapct += $6
form4 }
form4 printf("%s\t%s\t%d\t%.1f\t%d\t%.1f\t%.1f\n",
form4 $1, $2, $3, $4, $5, $6, $7)
form4 gpop += $3; gpoppct += $4
form4 garea += $5; gareapct += $6
form4 }
form4
form4 END {
form4 totalprint()
form4 print ".T&\nl s n n n n n."
form4 printf("GRAND TOTAL\t\t%d\t%.1f\t%d\t%.1f\n",
form4 gpop, gpoppct, garea, gareapct)
form4 print "", "=", "=", "=", "=", "="
form4 print ".TE"
form4 }