parsely 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/Rakefile +19 -0
  4. data/TODO +20 -0
  5. data/bin/parsely +4 -0
  6. data/lib/parsely.rb +264 -0
  7. data/parsely.gemspec +24 -0
  8. data/test/basic/001/command +1 -0
  9. data/test/basic/001/input.log +5 -0
  10. data/test/basic/001/output +5 -0
  11. data/test/basic/002/command +1 -0
  12. data/test/basic/002/input.log +3 -0
  13. data/test/basic/002/output +3 -0
  14. data/test/basic/003/command +1 -0
  15. data/test/basic/003/input.log +5 -0
  16. data/test/basic/003/output +1 -0
  17. data/test/basic/004/command +1 -0
  18. data/test/basic/004/input.log +5 -0
  19. data/test/basic/004/output +1 -0
  20. data/test/basic/005/command +1 -0
  21. data/test/basic/005/input.log +5 -0
  22. data/test/basic/005/output +5 -0
  23. data/test/basic/006/command +1 -0
  24. data/test/basic/006/input.log +5 -0
  25. data/test/basic/006/output +5 -0
  26. data/test/basic/007/command +1 -0
  27. data/test/basic/007/input.log +8 -0
  28. data/test/basic/007/output +5 -0
  29. data/test/basic/008/command +1 -0
  30. data/test/basic/008/input.log +3 -0
  31. data/test/basic/008/output +1 -0
  32. data/test/basic/009-if-global/command +1 -0
  33. data/test/basic/009-if-global/input.log +4 -0
  34. data/test/basic/009-if-global/output +2 -0
  35. data/test/basic/010-if-var/command +1 -0
  36. data/test/basic/010-if-var/input.log +4 -0
  37. data/test/basic/010-if-var/output +1 -0
  38. data/test/basic/011-sum-if/command +1 -0
  39. data/test/basic/011-sum-if/counts.txt +7 -0
  40. data/test/basic/011-sum-if/output +1 -0
  41. data/test/basic/012-sum-if-2/command +1 -0
  42. data/test/basic/012-sum-if-2/counts.txt +7 -0
  43. data/test/basic/012-sum-if-2/output +1 -0
  44. data/test/basic/013-if-non-math/command +1 -0
  45. data/test/basic/013-if-non-math/counts.txt +7 -0
  46. data/test/basic/013-if-non-math/output +1 -0
  47. data/test/basic/014-line-index/command +1 -0
  48. data/test/basic/014-line-index/counts.txt +7 -0
  49. data/test/basic/014-line-index/output +1 -0
  50. data/test/cli-runner.rb +20 -0
  51. metadata +152 -0
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in parsely.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ require 'bundler/gem_tasks'
2
+
3
+ ENV['PATH']+=':'+File.join(File.dirname(__FILE__),'bin/')
4
+ ENV['RUBYLIB']||=''
5
+ ENV['RUBYLIB']+=':'+File.join(File.dirname(__FILE__),'lib/')
6
+ task :default => [:test]
7
+
8
+ desc 'run tests'
9
+ task :test do
10
+ ruby "-Ilib test/cli-runner.rb"
11
+ end
12
+
13
+ desc 'create new test dir'
14
+ task :newtest, :name do |t, args|
15
+ old = Dir.entries('test/basic/').last
16
+ new = old[/^(\d+)/, 1].succ
17
+ new = new + '-' + args[:name] if args[:name]
18
+ cp_r 'test/basic/'+old, 'test/basic/'+new
19
+ end
data/TODO ADDED
@@ -0,0 +1,20 @@
1
+ - do by using regex to split on last by <field> and assume none if missing and just run as map over groups
2
+ - _2 in dump by _1 in other
3
+ - _2 in dump by _1 in other
4
+ + _1 if /www/
5
+ - _1 if _2 =~ x
6
+ - .parselyrc
7
+ - split by: if a X or not, or if _1 in other_file (subsides comm)
8
+ + in "foo 1\nbar 2" "sum(_2) if _2 < 3" to see how much I can delete
9
+ - _1._1 for submatch (e.g. user agent)
10
+ - index of <foo> (e.g. when something is processing ines and you want to check where it is)
11
+ - skip line e.g. 123\na\nb\nc -> parsely _2 unless idx = 0
12
+ - normalize e.g. uniq on
13
+ /?email=digest%40digg.com&name=&callback=jsonp1310305312089
14
+ /?email=digest%40digg.com&name=&callback=jsonp1310305312088
15
+ /?email=digest%40digg.com&name=&callback=jsonp1310305312085
16
+ /?email=digest%40digg.com&name=&callback=jsonp1310305312086
17
+ skip jsonp bit
18
+ summaryse is a cool extension from which to steal stuff. Maybe provide basic functionalities through that
19
+ - given [/m/09_pbpl /type/object/key /soft/isbn/9780491035453,..] and [/m/077601h /book/isbn/book_editions /m/09_pbpl] get [/m/09_pbpl /soft/isbn/9780491035453]
20
+ - use merge sorted and merge unsorted probably
data/bin/parsely ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'parsely'
4
+ Parsely.new.main
data/lib/parsely.rb ADDED
@@ -0,0 +1,264 @@
1
+ require 'set'
2
+ require 'English'
3
+ $OUTPUT_FIELD_SEPARATOR = ' '
4
+
5
+ def p args
6
+ STDERR.puts(args.inspect) #if $DEBUG
7
+ end
8
+
9
+ class PseudoBinding
10
+ class PerlVar < String
11
+ def <=> other
12
+ if other.is_a? Numeric
13
+ to_f <=> other
14
+ else
15
+ super
16
+ end
17
+ end
18
+ def inspect
19
+ "PerlVar(#{super})"
20
+ end
21
+ end
22
+ PerlNil = PerlVar.new ''
23
+ attr :line
24
+ def initialize lineno, vals
25
+ @line, @vals = lineno, vals.map {|x| PerlVar.new(x)}
26
+ end
27
+ def method_missing name, *args
28
+ if args.empty?
29
+ if name =~ /_(\d+)/
30
+ @vals[$1.to_i] || PerlNil
31
+ else
32
+ name.to_s
33
+ end
34
+ else
35
+ super
36
+ end
37
+ end
38
+ end
39
+ class String
40
+ def value
41
+ to_s
42
+ end
43
+ end
44
+ class Proc
45
+ attr_accessor :single
46
+ def value
47
+ call
48
+ end
49
+ end
50
+ class Parsely
51
+ VERSION = "0.1.1"
52
+ def self.cmd(&block)
53
+ klass = Struct.new :value, &block
54
+ klass.class_eval do
55
+ def process(items)
56
+ value.assign(items)
57
+ _process(value)
58
+ end
59
+ end
60
+ klass
61
+ end
62
+ RGX= /"(.*?)"|\[(.*?)\]|([^\s]+)/
63
+ Value = Struct.new :index, :value do
64
+ def assign(items)
65
+ self.value = items[index]
66
+ end
67
+ def process(items)
68
+ items[index]
69
+ end
70
+ def to_i
71
+ value.to_i
72
+ end
73
+ def to_f
74
+ value.to_f
75
+ end
76
+ def to_s
77
+ value.to_s
78
+ end
79
+ end
80
+ Ops = {
81
+ :min => cmd do
82
+ def initialize value
83
+ super
84
+ @running_value = Float::MAX #-Inf would be better
85
+ @result = proc { @running_value }
86
+ @result.single = true
87
+ end
88
+ def _process(value)
89
+ if value.to_f < @running_value
90
+ @running_value = value.to_f
91
+ end
92
+ @result
93
+ end
94
+ end,
95
+ :max => cmd do
96
+ def initialize index
97
+ super
98
+ @running_value = Float::MIN #-Inf would be better
99
+ @result = proc { @running_value }
100
+ @result.single = true
101
+ end
102
+ def _process(value)
103
+ if value.to_f > @running_value
104
+ @running_value = value.to_f
105
+ end
106
+ @result
107
+ end
108
+ end,
109
+ :sum => cmd do
110
+ def initialize index
111
+ super
112
+ @running_value = 0
113
+ @result = proc { @running_value }
114
+ @result.single = true
115
+ end
116
+ def _process(value)
117
+ @running_value += value.to_i
118
+ @result
119
+ end
120
+ end,
121
+ :avg => cmd do
122
+ def initialize index
123
+ super
124
+ @running_value = 0
125
+ @running_count = 0
126
+ @result = proc { @running_value/@running_count.to_f }
127
+ @result.single = true
128
+ end
129
+ def _process(value)
130
+ @running_value += value.to_i
131
+ @running_count += 1
132
+ @result
133
+ end
134
+ end,
135
+ :freq => cmd do
136
+ def initialize index
137
+ super
138
+ @running_freqs = Hash.new(0)
139
+ @running_count = 0
140
+ as_ary=nil
141
+ @result = proc do
142
+ if as_ary.nil?
143
+ as_ary=@running_freqs.sort_by do |k,v| [-v,k] end.each
144
+ end
145
+ k,v = as_ary.next
146
+ [v, k]
147
+ end
148
+ end
149
+ def _process(value)
150
+ @running_freqs[value.to_s]+=1
151
+ @running_count += 1
152
+ @result
153
+ end
154
+ end,
155
+ :stats => cmd do
156
+ def initialize index
157
+ require 'rubygems'
158
+ require 'ministat'
159
+ super
160
+ @running_values = []
161
+ cached = nil
162
+ @result = proc do
163
+ unless cached
164
+ data = MiniStat::Data.new(@running_values)
165
+ cached = {
166
+ "Mean"=>data.mean,
167
+ "Geometric Mean"=>data.geometric_mean,
168
+ "Harmonic Mean"=>data.harmonic_mean,
169
+ "Median"=>data.median ,
170
+ "Min"=>data.data.min ,
171
+ "Q1"=>data.q1,
172
+ "Q3"=>data.q3,
173
+ "Max"=>data.data.max,
174
+ "IQR"=>data.iqr,
175
+ "Outliers"=>data.outliers.inspect,
176
+ "Variance"=>data.variance ,
177
+ "Std Dev"=>data.std_dev,
178
+ }.sort.each
179
+ end
180
+ cached.next
181
+ end
182
+ end
183
+ def _process(value)
184
+ @running_values << value.to_i
185
+ @result
186
+ end
187
+ end,
188
+ }
189
+
190
+ def parse(expr)
191
+ val, cond = expr.split(/ if /)
192
+ # p [ val, cond]
193
+ elems=val.split
194
+ r=elems.map do |e|
195
+ case e
196
+ when /(\w+)\(\_(\d+)\)/
197
+ klass=Ops[$1.to_sym]
198
+ if klass.nil?
199
+ abort "unknown op '#$1'"
200
+ end
201
+ klass.new(Value.new($2.to_i))
202
+ when /\_(\d+)/
203
+ Value.new($1.to_i)
204
+ end
205
+ end
206
+ [r, parse_cond(cond)]
207
+ end
208
+
209
+ def parse_cond str
210
+ case str
211
+ when %r[/.*/]
212
+ proc { |bnd| bnd.instance_eval(str) === bnd._0 }
213
+ when nil, ''
214
+ proc { |bnd| true }
215
+ else
216
+ proc { |bnd| bnd.instance_eval(str) }
217
+ end
218
+ end
219
+
220
+ def main
221
+ if ARGV.empty?
222
+ abort("usage #$0 <expr> <file file file| stdin >")
223
+ end
224
+ expr = ARGV.shift
225
+ main_loop(expr,ARGF)
226
+ end
227
+
228
+ def main_loop(expr,lines)
229
+ ast, cond =parse(expr)
230
+ result = []
231
+ result = lines.map.with_index do |line, lineno|
232
+ line.chomp!
233
+ items = [line]+line.scan(RGX).map do |a|
234
+ # XXX horrible
235
+ a.find do |e|
236
+ !e.nil?
237
+ end
238
+ end
239
+ #XXX ugly
240
+ next unless items
241
+ b = PseudoBinding.new(lineno, items)
242
+ ast.map do |a|
243
+ a.process(items) if cond[b]
244
+ end
245
+ end
246
+ last = []
247
+ result.each do |cols|
248
+ result_line = cols.map do |col|
249
+ next if col.nil?
250
+ col.value
251
+ end.join.strip
252
+ same_results = cols.zip(last).map do |a,b|
253
+ a.respond_to?(:single) && a.single && a.object_id == b.object_id && !a.is_a?(Numeric)
254
+ end.all?
255
+ break if same_results
256
+ next if result_line.empty?
257
+ puts result_line
258
+ last = cols
259
+ end
260
+ rescue StopIteration
261
+ # end
262
+ end
263
+
264
+ end
data/parsely.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "parsely"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "parsely"
7
+ s.version = Parsely::VERSION
8
+ s.authors = ["Gabriele Renzi"]
9
+ s.email = ["rff.rff+parsely@gmail.com"]
10
+ s.homepage = "http://github.com/riffraff/parsely"
11
+ s.summary = %q{a simple tool for text file wrangling}
12
+ s.description = %q{parsely is a simple tool for managing text files.
13
+ Mostly to replace a lot of awk/sed/ruby/perl one-off scripts.
14
+ This is an internal release, guaranteed to break and ruin your life.}
15
+
16
+ #s.rubyforge_project = "parsely"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+ s.add_development_dependency "rake"
23
+
24
+ end
@@ -0,0 +1 @@
1
+ parsely '_1' input.log
@@ -0,0 +1,5 @@
1
+ 1 miao
2
+ 2 bau
3
+ 3
4
+ 4 er er er
5
+ 5
@@ -0,0 +1,5 @@
1
+ 1
2
+ 2
3
+ 3
4
+ 4
5
+ 5
@@ -0,0 +1 @@
1
+ parsely '_2, _3' input.log
@@ -0,0 +1,3 @@
1
+ ciao 1 2 bau
2
+ miao 2 3 lol
3
+ roar 9 10 argh
@@ -0,0 +1,3 @@
1
+ 1 2
2
+ 2 3
3
+ 9 10
@@ -0,0 +1 @@
1
+ parsely 'sum(_1)' input.log
@@ -0,0 +1,5 @@
1
+ 1 miao
2
+ 2 bau
3
+ 3
4
+ 4 er er er
5
+ 5
@@ -0,0 +1 @@
1
+ 15
@@ -0,0 +1 @@
1
+ parsely 'avg(_1)' input.log
@@ -0,0 +1,5 @@
1
+ 1 miao
2
+ 2 bau
3
+ 3
4
+ 4 er er er
5
+ 5
@@ -0,0 +1 @@
1
+ 3.0
@@ -0,0 +1 @@
1
+ parsely '_1 _2' input.log
@@ -0,0 +1,5 @@
1
+ 1 miao
2
+ 2 bau
3
+ 3
4
+ 4 er er er
5
+ 5
@@ -0,0 +1,5 @@
1
+ 1 miao
2
+ 2 bau
3
+ 3
4
+ 4 er
5
+ 5
@@ -0,0 +1 @@
1
+ parsely 'avg(_1) sum(_1) _2' input.log
@@ -0,0 +1,5 @@
1
+ 1 miao
2
+ 2 bau
3
+ 3
4
+ 4 er er er
5
+ 5
@@ -0,0 +1,5 @@
1
+ 3.0 15 miao
2
+ 3.0 15 bau
3
+ 3.0 15
4
+ 3.0 15 er
5
+ 3.0 15
@@ -0,0 +1 @@
1
+ parsely 'freq(_1)' input.log
@@ -0,0 +1,8 @@
1
+ 1 miao
2
+ 1 again
3
+ 1 more
4
+ 2 bau
5
+ 2 again
6
+ 3
7
+ 4 er er er
8
+ 5
@@ -0,0 +1,5 @@
1
+ 3 1
2
+ 2 2
3
+ 1 3
4
+ 1 4
5
+ 1 5
@@ -0,0 +1 @@
1
+ parsely 'min(_1) max(_2)' input.log
@@ -0,0 +1,3 @@
1
+ 1.5 10
2
+ 2.9 20
3
+ 3 30
@@ -0,0 +1 @@
1
+ 1.5 30.0
@@ -0,0 +1 @@
1
+ parsely '_0 if /www/' input.log
@@ -0,0 +1,4 @@
1
+ ignore
2
+ www bla bla
3
+ ignore again
4
+ something www
@@ -0,0 +1,2 @@
1
+ www bla bla
2
+ something www
@@ -0,0 +1 @@
1
+ parsely '_0 if _1 == www' input.log
@@ -0,0 +1,4 @@
1
+ ignore
2
+ www bla bla
3
+ ignore again
4
+ something www
@@ -0,0 +1 @@
1
+ www bla bla
@@ -0,0 +1 @@
1
+ parsely 'sum(_2) if _2 < 3' counts.txt
@@ -0,0 +1,7 @@
1
+ keep 10
2
+ kep 5
3
+ foo 1
4
+ bar 1
5
+ baz 2
6
+ quux 3
7
+
@@ -0,0 +1 @@
1
+ 4
@@ -0,0 +1 @@
1
+ parsely 'sum(_2) if _2 < 3 && _1 != skip' counts.txt
@@ -0,0 +1,7 @@
1
+ keep 10
2
+ kep 5
3
+ foo 1
4
+ bar 1
5
+ baz 2
6
+ quux 3
7
+
@@ -0,0 +1 @@
1
+ 4
@@ -0,0 +1 @@
1
+ parsely 'sum(_2) if _1[0] == ?k' counts.txt
@@ -0,0 +1,7 @@
1
+ keep 10
2
+ kep 5
3
+ foo 1
4
+ bar 1
5
+ baz 2
6
+ quux 3
7
+
@@ -0,0 +1 @@
1
+ 15
@@ -0,0 +1 @@
1
+ parsely 'sum(_2) if line == 0' counts.txt
@@ -0,0 +1,7 @@
1
+ keep 10
2
+ no 5
3
+ foo 1
4
+ bar 1
5
+ baz 2
6
+ quux 3
7
+
@@ -0,0 +1 @@
1
+ 10
@@ -0,0 +1,20 @@
1
+ require 'test/unit'
2
+
3
+ p ENV['PATH']
4
+ def make_runner(dir)
5
+ klass= Class.new Test::Unit::TestCase do
6
+ test_dir = File.expand_path("test/#{dir}/0*")
7
+ Dir[test_dir].each do |d|
8
+ define_method 'test_'+dir+'_'+d.split("/").last do
9
+ Dir.chdir(d)
10
+ command = File.read('command')
11
+ output= `#{command} 2>&1`
12
+ expected = File.read('output')
13
+ assert_equal expected.chomp.strip, output.chomp.strip
14
+ end
15
+ end
16
+ end
17
+ Object.const_set 'Test_'+dir, klass
18
+ end
19
+ make_runner 'basic'
20
+
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parsely
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gabriele Renzi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-07-14 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &2153010780 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2153010780
25
+ description: ! "parsely is a simple tool for managing text files.\n Mostly
26
+ to replace a lot of awk/sed/ruby/perl one-off scripts.\n This
27
+ is an internal release, guaranteed to break and ruin your life."
28
+ email:
29
+ - rff.rff+parsely@gmail.com
30
+ executables:
31
+ - parsely
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - .gitignore
36
+ - Gemfile
37
+ - Rakefile
38
+ - TODO
39
+ - bin/parsely
40
+ - lib/parsely.rb
41
+ - parsely.gemspec
42
+ - test/basic/001/command
43
+ - test/basic/001/input.log
44
+ - test/basic/001/output
45
+ - test/basic/002/command
46
+ - test/basic/002/input.log
47
+ - test/basic/002/output
48
+ - test/basic/003/command
49
+ - test/basic/003/input.log
50
+ - test/basic/003/output
51
+ - test/basic/004/command
52
+ - test/basic/004/input.log
53
+ - test/basic/004/output
54
+ - test/basic/005/command
55
+ - test/basic/005/input.log
56
+ - test/basic/005/output
57
+ - test/basic/006/command
58
+ - test/basic/006/input.log
59
+ - test/basic/006/output
60
+ - test/basic/007/command
61
+ - test/basic/007/input.log
62
+ - test/basic/007/output
63
+ - test/basic/008/command
64
+ - test/basic/008/input.log
65
+ - test/basic/008/output
66
+ - test/basic/009-if-global/command
67
+ - test/basic/009-if-global/input.log
68
+ - test/basic/009-if-global/output
69
+ - test/basic/010-if-var/command
70
+ - test/basic/010-if-var/input.log
71
+ - test/basic/010-if-var/output
72
+ - test/basic/011-sum-if/command
73
+ - test/basic/011-sum-if/counts.txt
74
+ - test/basic/011-sum-if/output
75
+ - test/basic/012-sum-if-2/command
76
+ - test/basic/012-sum-if-2/counts.txt
77
+ - test/basic/012-sum-if-2/output
78
+ - test/basic/013-if-non-math/command
79
+ - test/basic/013-if-non-math/counts.txt
80
+ - test/basic/013-if-non-math/output
81
+ - test/basic/014-line-index/command
82
+ - test/basic/014-line-index/counts.txt
83
+ - test/basic/014-line-index/output
84
+ - test/cli-runner.rb
85
+ homepage: http://github.com/riffraff/parsely
86
+ licenses: []
87
+ post_install_message:
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 1.8.5
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: a simple tool for text file wrangling
109
+ test_files:
110
+ - test/basic/001/command
111
+ - test/basic/001/input.log
112
+ - test/basic/001/output
113
+ - test/basic/002/command
114
+ - test/basic/002/input.log
115
+ - test/basic/002/output
116
+ - test/basic/003/command
117
+ - test/basic/003/input.log
118
+ - test/basic/003/output
119
+ - test/basic/004/command
120
+ - test/basic/004/input.log
121
+ - test/basic/004/output
122
+ - test/basic/005/command
123
+ - test/basic/005/input.log
124
+ - test/basic/005/output
125
+ - test/basic/006/command
126
+ - test/basic/006/input.log
127
+ - test/basic/006/output
128
+ - test/basic/007/command
129
+ - test/basic/007/input.log
130
+ - test/basic/007/output
131
+ - test/basic/008/command
132
+ - test/basic/008/input.log
133
+ - test/basic/008/output
134
+ - test/basic/009-if-global/command
135
+ - test/basic/009-if-global/input.log
136
+ - test/basic/009-if-global/output
137
+ - test/basic/010-if-var/command
138
+ - test/basic/010-if-var/input.log
139
+ - test/basic/010-if-var/output
140
+ - test/basic/011-sum-if/command
141
+ - test/basic/011-sum-if/counts.txt
142
+ - test/basic/011-sum-if/output
143
+ - test/basic/012-sum-if-2/command
144
+ - test/basic/012-sum-if-2/counts.txt
145
+ - test/basic/012-sum-if-2/output
146
+ - test/basic/013-if-non-math/command
147
+ - test/basic/013-if-non-math/counts.txt
148
+ - test/basic/013-if-non-math/output
149
+ - test/basic/014-line-index/command
150
+ - test/basic/014-line-index/counts.txt
151
+ - test/basic/014-line-index/output
152
+ - test/cli-runner.rb