-
Notifications
You must be signed in to change notification settings - Fork 6
/
example_test.go
241 lines (213 loc) · 7.18 KB
/
example_test.go
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
// This file presents some examples of awk package usage.
package awk_test
import (
"fmt"
"github.com/spakin/awk"
"os"
"sort"
)
var s *awk.Script
// Write to the standard output all input lines for which field 3 is
// greater than 5 (AWK: $3 > 5).
func Example_01() {
s.AppendStmt(func(s *awk.Script) bool { return s.F(3).Int() > 5 }, nil)
}
// Write every tenth line (AWK: (NR % 10) == 0).
func Example_02() {
s.AppendStmt(func(s *awk.Script) bool { return s.NR%10 == 0 }, nil)
}
// Write any line with a substring containing a 'G' or 'D', followed by a
// sequence of digits and characters (AWK:
// /(G|D)([[:digit:][:alpha:]]*)/). This example uses character classes digit
// and alpha to match language-independent digit and alphabetic characters
// respectively.
func Example_04() {
s.AppendStmt(func(s *awk.Script) bool { return s.F(0).Match("(G|D)([[:digit:][:alpha:]]*)") }, nil)
}
// Write any line in which the second field matches the regular expression
// "xyz" and the fourth field does not (AWK: $2 ~ /xyz/ && $4 !~ /xyz/).
func Example_05() {
s.AppendStmt(func(s *awk.Script) bool {
return s.F(2).Match("xyz") && !s.F(4).Match("xyz")
}, nil)
}
// Write any line in which the second field contains a backslash (AWK: $2 ~
// /\\/).
func Example_06() {
s.AppendStmt(func(s *awk.Script) bool { return s.F(2).Match(`\\`) }, nil)
}
// Write the second to the last and the last field in each line. Separate the
// fields by a colon (AWK: {OFS=":"; print $(NF-1), $NF}).
func Example_08() {
s.AppendStmt(nil, func(s *awk.Script) { fmt.Printf("%v:%v\n", s.F(s.NF-1), s.F(s.NF)) })
}
// Write the line number and number of fields in each line (AWK: {print NR ":"
// NF}). The three strings representing the line number, the colon, and the
// number of fields are concatenated and that string is written to standard
// output.
func Example_09() {
s.AppendStmt(nil, func(s *awk.Script) { fmt.Printf("%d:%d\n", s.NR, s.NF) })
}
// Write lines longer than 72 characters (AWK: length($0) > 72).
func Example_10() {
s.AppendStmt(func(s *awk.Script) bool { return len(s.F(0).String()) > 72 }, nil)
}
// Write the first two fields in opposite order (AWK: {print $2, $1}).
func Example_11() {
s.AppendStmt(nil, func(s *awk.Script) { s.Println(s.F(2), s.F(1)) })
}
// Do the same as Example 11, with input fields separated by a comma, space and
// tab characters, or both (AWK:
//
// BEGIN { FS = ",[ \t]*|[ \t]+" }
// { print $2, $1 }
//
// ).
func Example_12() {
s.Begin = func(s *awk.Script) { s.SetFS(",[ \t]*|[ \t]+") }
s.AppendStmt(nil, func(s *awk.Script) { s.Println(s.F(2), s.F(1)) })
}
// Add up the first column and print the sum and average (AWK:
//
// {s += $1 }
// END {print "sum is", s, "average is", s/NR}
//
// ).
func Example_13() {
s.Begin = func(s *awk.Script) { s.State = 0.0 }
s.AppendStmt(nil, func(s *awk.Script) { s.State = s.State.(float64) + s.F(1).Float64() })
s.End = func(s *awk.Script) {
sum := s.State.(float64)
s.Println("sum is", sum, "average is", sum/float64(s.NR))
}
}
// Write fields in reverse order, one per line (many lines out for each line
// in). AWK: {for (i = NF; i > 0; --i) print $i}.
func Example_14() {
s.AppendStmt(nil, func(s *awk.Script) {
for i := s.NF; i > 0; i-- {
s.Println(s.F(i))
}
})
}
// Write all lines between occurrences of the strings "start" and "stop" (AWK:
// /start/, /stop/). This version of the Go code uses awk.Range to combine
// begin and end functions into a match range.
func Example_15a() {
s.AppendStmt(awk.Range(func(s *awk.Script) bool { return s.F(1).Match("start") },
func(s *awk.Script) bool { return s.F(1).Match("stop") }),
nil)
}
// Write all lines between occurrences of the strings "start" and "stop" (AWK:
// /start/, /stop/). This version of the Go code uses awk.Auto to define the
// begin and end conditions as simple regular-expression matches.
func Example_15b() {
s.AppendStmt(awk.Auto("start", "stop"), nil)
}
// Write all lines whose first field is different from the previous line's
// first field (AWK: $1 != prev {print; prev = $1}).
func Example_16() {
s.State = s.NewValue("")
s.AppendStmt(func(s *awk.Script) bool { return !s.F(1).StrEqual(s.State) },
func(s *awk.Script) {
s.Println()
s.State = s.F(1)
})
}
// For all rows of the form "Total: <number>", accumulate <number>. Once all
// rows have been read, output the grand total.
func ExampleScript_AppendStmt() {
s := awk.NewScript()
s.State = 0.0
s.AppendStmt(func(s *awk.Script) bool { return s.NF == 2 && s.F(1).StrEqual("Total:") },
func(s *awk.Script) { s.State = s.State.(float64) + s.F(2).Float64() })
s.End = func(s *awk.Script) { fmt.Printf("The grand total is %.2f\n", s.State.(float64)) }
s.Run(os.Stdin)
}
// Output each line preceded by its line number.
func ExampleScript_AppendStmt_nilPattern() {
s := awk.NewScript()
s.AppendStmt(nil, func(s *awk.Script) { fmt.Printf("%4d %v\n", s.NR, s.F(0)) })
s.Run(os.Stdin)
}
// Output only rows in which the first column contains a larger number than the
// second column.
func ExampleScript_AppendStmt_nilAction() {
s := awk.NewScript()
s.AppendStmt(func(s *awk.Script) bool { return s.F(1).Int() > s.F(2).Int() }, nil)
s.Run(os.Stdin)
}
// Output all input lines that appear between "BEGIN" and "END" inclusive.
func ExampleRange() {
s := awk.NewScript()
s.AppendStmt(awk.Range(func(s *awk.Script) bool { return s.F(1).StrEqual("BEGIN") },
func(s *awk.Script) bool { return s.F(1).StrEqual("END") }),
nil)
s.Run(os.Stdin)
}
// Extract the first column of the input into a slice of strings.
func ExampleBegin() {
var data []string
s := awk.NewScript()
s.Begin = func(s *awk.Script) {
s.SetFS(",")
data = make([]string, 0)
}
s.AppendStmt(nil, func(s *awk.Script) { data = append(data, s.F(1).String()) })
s.Run(os.Stdin)
}
// Output each line with its columns in reverse order.
func ExampleScript_F() {
s := awk.NewScript()
s.AppendStmt(nil, func(s *awk.Script) {
for i := s.NF; i > 0; i-- {
if i > 1 {
fmt.Printf("%v ", s.F(i))
} else {
fmt.Printf("%v\n", s.F(i))
}
}
})
s.Run(os.Stdin)
}
// Allocate and populate a 2-D array. The diagonal is made up of strings while
// the rest of the array consists of float64 values.
func ExampleValueArray_Set() {
va := s.NewValueArray()
diag := []string{"Dasher", "Dancer", "Prancer", "Vixen", "Comet", "Cupid", "Dunder", "Blixem"}
for i := 0; i < 8; i++ {
for j := 0; j < 8; j++ {
if i == j {
va.Set(i, j, diag[i])
} else {
va.Set(i, j, float64(i*8+j)/63.0)
}
}
}
}
// Sort each line's columns, which are assumed to be floating-point numbers.
func ExampleScript_FFloat64s() {
s := awk.NewScript()
s.AppendStmt(nil, func(s *awk.Script) {
nums := s.FFloat64s()
sort.Float64s(nums)
for _, n := range nums[:len(nums)-1] {
fmt.Printf("%.5g ", n)
}
fmt.Printf("%.5g\n", nums[len(nums)-1])
})
s.Run(os.Stdin)
}
// Delete the fifth line of the input stream but output all other lines.
func ExampleAuto_int() {
s := awk.NewScript()
s.AppendStmt(awk.Auto(5), func(s *awk.Script) { s.Next() })
s.AppendStmt(nil, nil)
s.Run(os.Stdin)
}
// Output only those lines containing the string, "fnord".
func ExampleAuto_string() {
s := awk.NewScript()
s.AppendStmt(awk.Auto("fnord"), nil)
s.Run(os.Stdin)
}