jgrep 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/jgrep +2 -1
- data/jgrep.gemspec +3 -2
- data/lib/jgrep.rb +125 -21
- data/lib/parser/scanner.rb +16 -0
- metadata +17 -6
data/bin/jgrep
CHANGED
@@ -8,7 +8,7 @@ options = {:flat => false, :start => nil}
|
|
8
8
|
begin
|
9
9
|
OptionParser.new do |opts|
|
10
10
|
opts.banner = "Usage: jgrep [options] \"expression\""
|
11
|
-
opts.on("-s", "--simple
|
11
|
+
opts.on("-s", "--simple [FIELDS]", "Display only one or more fields from each of the resulting json documents") do |field|
|
12
12
|
if (field.split(" ")).size > 1
|
13
13
|
options[:field] = field.split(" ")
|
14
14
|
else
|
@@ -87,6 +87,7 @@ begin
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
end
|
90
|
+
|
90
91
|
rescue Exception => e
|
91
92
|
STDERR.puts "Error - #{e}"
|
92
93
|
exit 1
|
data/jgrep.gemspec
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "jgrep"
|
3
|
-
s.version = "1.
|
3
|
+
s.version = "1.3.0"
|
4
4
|
|
5
5
|
s.authors = ["P Loubser"]
|
6
|
-
s.date = %q{2011-08-
|
6
|
+
s.date = %q{2011-08-04}
|
7
7
|
s.default_executable = "jgrep"
|
8
|
+
s.add_dependency('json')
|
8
9
|
s.description = "Compare a list of json documents to a simple logical language and returns matches as output"
|
9
10
|
s.email = ["ploubser@gmail.com"]
|
10
11
|
s.executables = ["jgrep"]
|
data/lib/jgrep.rb
CHANGED
@@ -4,6 +4,7 @@ require 'parser/parser.rb'
|
|
4
4
|
require 'parser/scanner.rb'
|
5
5
|
require 'rubygems'
|
6
6
|
require 'json'
|
7
|
+
#require 'yajl/json_gem'
|
7
8
|
|
8
9
|
module JGrep
|
9
10
|
@verbose = false
|
@@ -17,7 +18,10 @@ module JGrep
|
|
17
18
|
@flatten = true
|
18
19
|
end
|
19
20
|
|
20
|
-
#
|
21
|
+
#Parse json and return documents that match the logical expression
|
22
|
+
#Filters define output by limiting it to only returning a the listed keys.
|
23
|
+
#Start allows you to move the pointer indicating where parsing starts.
|
24
|
+
#Default is the first key in the document heirarchy
|
21
25
|
def self.jgrep(json, expression, filters = nil, start = nil)
|
22
26
|
errors = ""
|
23
27
|
begin
|
@@ -66,6 +70,78 @@ module JGrep
|
|
66
70
|
STDERR.puts "Error. Invalid JSON given"
|
67
71
|
exit 1
|
68
72
|
end
|
73
|
+
end
|
74
|
+
|
75
|
+
#Convert a specific hash inside a JSON document to an array
|
76
|
+
#Mark is a string in the format foo.bar.baz that points to
|
77
|
+
#the array in the document.
|
78
|
+
def self.hash_to_array(documents, mark)
|
79
|
+
|
80
|
+
begin
|
81
|
+
documents = JSON.parse(documents)
|
82
|
+
rescue JSON::ParserError => e
|
83
|
+
STDERR.puts "Error. Invalid JSON given"
|
84
|
+
exit 1
|
85
|
+
end
|
86
|
+
|
87
|
+
result = []
|
88
|
+
|
89
|
+
begin
|
90
|
+
for i in 0..(documents.size - 1) do
|
91
|
+
tmp = documents[i]
|
92
|
+
unless mark == ""
|
93
|
+
mark.split(".").each_with_index do |m,i|
|
94
|
+
tmp = tmp[m] unless i == mark.split(".").size - 1
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
tmp[mark.split.last].each{|d| result << {"value" => d[1], "key" => d[0]}}
|
99
|
+
tmp[mark.split.last] = result
|
100
|
+
|
101
|
+
end
|
102
|
+
rescue Exception => e
|
103
|
+
STDERR.puts "Error. Invalid position specified in JSON document"
|
104
|
+
exit!
|
105
|
+
end
|
106
|
+
|
107
|
+
puts JSON.pretty_generate(documents)
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
#Convert a specific array inside a JSON document to a hash
|
112
|
+
#Mark is a string in the format foo.bar.baz that points to
|
113
|
+
#the hash in the document. Each element in the array will
|
114
|
+
#be turned into a hash in the format key => array[x]
|
115
|
+
def self.array_to_hash(documents, mark, key)
|
116
|
+
|
117
|
+
begin
|
118
|
+
documents = JSON.parse(documents)
|
119
|
+
rescue JSON::ParserError => e
|
120
|
+
STDERR.puts "Error. Invalid JSON given"
|
121
|
+
exit 1
|
122
|
+
end
|
123
|
+
|
124
|
+
result = {}
|
125
|
+
|
126
|
+
begin
|
127
|
+
for i in 0..(documents.size - 1) do
|
128
|
+
tmp = documents[i]
|
129
|
+
unless mark == ""
|
130
|
+
mark.split(".").each_with_index do |m,i|
|
131
|
+
tmp = tmp[m] unless i == mark.split(".").size - 1
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
tmp[mark.split(".").last].each{|d| result[d[key]] = d}
|
136
|
+
tmp[mark.split(".").last] = result
|
137
|
+
|
138
|
+
end
|
139
|
+
rescue Exception => e
|
140
|
+
STDERR.puts "Error. Invalid position specified in JSON document"
|
141
|
+
exit!
|
142
|
+
end
|
143
|
+
|
144
|
+
puts JSON.pretty_generate(documents)
|
69
145
|
|
70
146
|
end
|
71
147
|
|
@@ -128,6 +204,8 @@ module JGrep
|
|
128
204
|
end
|
129
205
|
end
|
130
206
|
|
207
|
+
|
208
|
+
#Check if the json key that is defined by statement is defined in the json document
|
131
209
|
def self.present?(document, statement)
|
132
210
|
statement.split(".").each do |key|
|
133
211
|
if document.is_a? Hash
|
@@ -167,25 +245,25 @@ module JGrep
|
|
167
245
|
op = statement
|
168
246
|
end
|
169
247
|
|
170
|
-
tmp = document
|
248
|
+
tmp = dig_path(document, key)
|
171
249
|
|
172
|
-
|
173
|
-
tmp = tmp
|
174
|
-
if tmp.nil?
|
175
|
-
if item == key.split(".").last
|
176
|
-
tmp = "null"
|
177
|
-
else
|
178
|
-
return false
|
179
|
-
end
|
180
|
-
end
|
181
|
-
result = false
|
182
|
-
if tmp.is_a? Array
|
183
|
-
return (is_object_in_array?(tmp, "#{key.split(".")[i+1]}#{op}#{value}"))
|
184
|
-
end
|
250
|
+
if tmp.is_a?(Array) and tmp.size == 1
|
251
|
+
tmp = tmp.first
|
185
252
|
end
|
186
253
|
|
187
254
|
tmp, value = format(tmp, (value.gsub(/"|'/, "") unless value.nil?))
|
188
255
|
|
256
|
+
#Deal with null comparison
|
257
|
+
if tmp.nil? and value == "null"
|
258
|
+
return true
|
259
|
+
end
|
260
|
+
|
261
|
+
#Deal with regex matching
|
262
|
+
if ((value =~ /^\/.*\/$/) && tmp != nil)
|
263
|
+
(tmp.match(Regexp.new(value.gsub("/", "")))) ? (return true) : (return false)
|
264
|
+
end
|
265
|
+
|
266
|
+
#Deal with everything else
|
189
267
|
case op
|
190
268
|
when "="
|
191
269
|
(tmp == value) ? (return true) : (return false)
|
@@ -292,24 +370,50 @@ module JGrep
|
|
292
370
|
return eval(result.join(" "))
|
293
371
|
end
|
294
372
|
|
373
|
+
#Digs to a specific path in the json document and returns the value
|
295
374
|
def self.dig_path(json, path)
|
296
375
|
|
297
|
-
|
376
|
+
path = path.gsub(/^\./, "")
|
377
|
+
|
378
|
+
if path == ""
|
379
|
+
return json
|
380
|
+
end
|
381
|
+
|
382
|
+
if json.is_a? Hash
|
383
|
+
json.keys.each do |k|
|
384
|
+
if path.match(/^#{k}/) && k.match(/\./)
|
385
|
+
return dig_path(json[k], path.gsub(k, ""))
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
path_array=path.split(".")
|
391
|
+
|
392
|
+
if path_array.first == "*"
|
393
|
+
tmp = []
|
394
|
+
json.each do |j|
|
395
|
+
tmp << dig_path(j[1], path_array.drop(1).join("."))
|
396
|
+
end
|
397
|
+
return tmp
|
398
|
+
|
399
|
+
end
|
400
|
+
|
401
|
+
json = json[path_array.first] if json.is_a? Hash
|
298
402
|
|
299
|
-
if json.is_a?
|
300
|
-
if path ==
|
403
|
+
if json.is_a? Hash
|
404
|
+
if path == path_array.first
|
301
405
|
return json
|
302
406
|
else
|
303
|
-
return dig_path(json, (path.match(/\./) ?
|
407
|
+
return dig_path(json, (path.match(/\./) ? path_array.drop(1).join(".") : path))
|
304
408
|
end
|
305
409
|
|
306
410
|
elsif json.is_a? Array
|
307
|
-
if path ==
|
411
|
+
if path == path_array.first && (json.first.is_a?(Hash) && !(json.first.keys.include?(path)))
|
308
412
|
return json
|
309
413
|
else
|
310
414
|
tmp = []
|
311
415
|
json.each do |j|
|
312
|
-
tmp_path = dig_path(j, (path.match(/\./) ?
|
416
|
+
tmp_path = dig_path(j, (path.match(/\./) ? path_array.drop(1).join(".") : path))
|
313
417
|
unless tmp_path.nil?
|
314
418
|
tmp << tmp_path
|
315
419
|
end
|
data/lib/parser/scanner.rb
CHANGED
@@ -46,6 +46,14 @@ module JGrep
|
|
46
46
|
gen_statement
|
47
47
|
end
|
48
48
|
|
49
|
+
when "&"
|
50
|
+
if(@arguments.split("")[@token_index +1] == "&")
|
51
|
+
@token_index +=1
|
52
|
+
return "and", "and"
|
53
|
+
else
|
54
|
+
gen_statement
|
55
|
+
end
|
56
|
+
|
49
57
|
when "o"
|
50
58
|
if (@arguments.split("")[@token_index + 1] == "r") && ((@arguments.split("")[@token_index + 2] == " ") || (@arguments.split("")[@token_index + 2] == "("))
|
51
59
|
@token_index += 1
|
@@ -54,6 +62,14 @@ module JGrep
|
|
54
62
|
gen_statement
|
55
63
|
end
|
56
64
|
|
65
|
+
when "|"
|
66
|
+
if(@arguments.split("")[@token_index +1] == "|")
|
67
|
+
@token_index +=1
|
68
|
+
return "or", "or"
|
69
|
+
else
|
70
|
+
gen_statement
|
71
|
+
end
|
72
|
+
|
57
73
|
when "+"
|
58
74
|
value = ""
|
59
75
|
i = @token_index + 1
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 1.
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 1.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- P Loubser
|
@@ -14,10 +14,21 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-08-
|
17
|
+
date: 2011-08-04 00:00:00 +01:00
|
18
18
|
default_executable: jgrep
|
19
|
-
dependencies:
|
20
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: json
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
21
32
|
description: Compare a list of json documents to a simple logical language and returns matches as output
|
22
33
|
email:
|
23
34
|
- ploubser@gmail.com
|