Skip to content

Instantly share code, notes, and snippets.

@djspiewak
Created February 10, 2015 19:27
Show Gist options
  • Save djspiewak/6cf5df6f64dcdbd95e97 to your computer and use it in GitHub Desktop.
Save djspiewak/6cf5df6f64dcdbd95e97 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
require 'json'
DESC_HEAD = /^\.([^\.\[]+)/
DEREF_HEAD = /^\[(\d+)\]/
def usage
$stderr.puts <<USAGE
usage: json descriptor
A descriptor consists of the following potential components in series:
.field Descends into the "field" key of an object
[num] Descends into the "num" index of an array
. The root descriptor (cannot be chained)
JSON is parsed from stdin and the output is printed to stdout. If no elements
of the input JSON match the specified descriptor, the output will be empty.
EXAMPLE
$ cat > /tmp/test.json
{
"user": {
"firstname": "Daniel",
"lastname": "Spiewak"
},
"magic": {
"keys": [
{
"id": 42,
"hash": "abcdef09876"
},
{
"id": 11,
"hash": "1234cafebabe"
}
]
}
}
^D
$ json .user.firstname < /tmp/test.json
Daniel
$ json .magic.keys[1].id < /tmp/test.json
11
USAGE
end
def descend(field)
lambda { |input| input[field] }
end
def parse_descriptor(descriptor)
if descriptor.strip.empty?
[]
else
if DESC_HEAD =~ descriptor
[descend($1)] + parse_descriptor($')
elsif DEREF_HEAD =~ descriptor
[descend($1.to_i)] + parse_descriptor($')
elsif '.' == descriptor
[lambda { |x| x }]
else
$stderr.puts "Unrecognized desctiptor '#{descriptor}'"
exit -1
end
end
end
if ARGV.length != 1
usage
exit -1
end
actions = parse_descriptor ARGV.first
input = JSON.load $stdin
result = actions.inject input do |acc, f|
f.call acc
end
$stdout.puts result.to_s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment