#!/usr/bin/env ruby # # William Stearns # Copyright (c) 2013, William Stearns # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the CloudPassage, Inc. nor the # names of its contributors may be used to endorse or promote products # derived from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL CLOUDPASSAGE, INC. BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED ANDON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # you may need to install the optparse, and json gems with: # sudo gem install optparse json #Version 0.5 #======== User-modifiable values #======== End of user-modifiable values #======== Functions #======== End of functions #======== Loadable modules require 'rubygems' require 'optparse' require 'json' #======== End of loadable modules #======== Initialization array_name = "" filters = [ ] connector_is_and = true #======== End of initialization optparse = OptionParser.new do |opts| opts.banner = "Print only certain elements of the top level array in a json block. Usage: jsonfilter.rb [options]" opts.on("-a array_name", "Array name") do |array_name_input| array_name = array_name_input end opts.on("-f filter", "Filter") do |filter_input| filters << filter_input.split(" ",3) unless filters.include?(filter_input.split(" ",3)) end opts.on("-o", "--or", "Change boolean connector to \"or\"") do connector_is_and = false end opts.on_tail("-h", "--help", "Show help text") do $stderr.puts opts exit end end optparse.parse! raw_stdin_string = $stdin.read.gsub(/\n/," ") insplit = raw_stdin_string.match(/^([^\{]*)(\{.*\})([^\}]*)/) prefix = insplit[1] raw_stdin = JSON insplit[2] postfix = insplit[3] json_to_print = "{ \"#{array_name}\": [" displayed = 0 raw_stdin[array_name].each do |one_block| #Start with "true" if the tests are connected by "and", start with "false" if connected by "or" display = connector_is_and filters.each do |one_filter| case one_filter[1] when "==", "=" #Must reverse logic to remove entries if the connector is "and" display = (not connector_is_and) if connector_is_and ^ (one_block[one_filter[0]] == one_filter[2]) when "!=" display = (not connector_is_and) if connector_is_and ^ (one_block[one_filter[0]] != one_filter[2]) when ">" #FIXME - can we remove .to_i to allow string comparisons as well? display = (not connector_is_and) if connector_is_and ^ (one_block[one_filter[0]].to_i > one_filter[2].to_i) when "<" display = (not connector_is_and) if connector_is_and ^ (one_block[one_filter[0]].to_i < one_filter[2].to_i) when "<=" display = (not connector_is_and) if connector_is_and ^ (one_block[one_filter[0]].to_i <= one_filter[2].to_i) when ">=" display = (not connector_is_and) if connector_is_and ^ (one_block[one_filter[0]].to_i >= one_filter[2].to_i) else $stderr.puts "Operator #{one_filter[1]} is not yet implemented, exiting." exit 1 end end if display #$stderr.print '+' if displayed > 0 json_to_print += "," end displayed += 1 json_to_print += one_block.to_json.to_s #else # $stderr.print '.' end end $stderr.flush json_to_print += "\n]" #Delete the array we've been working with; if there's anything left, we'll send it out unmodified raw_stdin.delete(array_name) if raw_stdin.length > 0 json_to_print += "," #Print the remaining hash, minus the first ("{") and last ("}") characters json_to_print += raw_stdin.to_json[1,raw_stdin.to_json.length-2] end json_to_print += " }" puts prefix puts JSON.pretty_generate(JSON json_to_print) puts postfix #$stderr.puts " Complete."