jgrep 1.2.1 → 1.3.0
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.
- 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
|