A cli JSON processor

Let me introduce jop, a command-line JSON processor powered by node.js.

jop is able to filter, sort, transform JSON input via a pipeline of operations.

 → cat people.json
[{"name":"Andrea","age":19},{"name":"Beatrice", "age": 21},{"name":"Carlo", "age":16}]

 → jop --findall "it.age > 18" -p people.json 
[
  {
    "name": "Andrea",
    "age": 19
  },
  {
    "name": "Beatrice",
    "age": 21
  }
]

 → jop --findall "it.age > 18" --collect "name" people.json 
[ "Andrea", "Beatrice" ]

Many operations are available:

Options:
  -c, --count      Count all elements in input                                                      
  --countby        Count elements in input grouping by the given expression                         
  -f, --findall    Find all elements satisfying given expression                                    
  --find           Find first element satisfying given expression                                   
  -g, --groupby    Group input elements using given expression                                      
  --indexof        Find index of the first element matching the given expression                    
  --lastindexof    Find index of the last element matching the given expression                     
  --collect        Collect the value of the given property name the input collection                
  --min            Find the element having the max output for the given expression                  
  --max            Find the element having the min output for the given expression                  
  --head           Return the first n nodes, where n is a given number            
  -s, --sortby     Sort input elements using the optionally provided expression                     
  --sample         Get n random elments from input, where n is a given number        
  -t, --transform  Transform input node using the given expression
  --tail           Return last n elements, where n is a given number       
  -p, --pretty     Pretty-print output                                                              
  --prop           Return value for a given property name                                           
  --keys           Collect object keys from input                                                   
  --values         Collect object values from input

Some operations require a javascript expression that is evaluated on each item of the input collection to perform the requested manipulation. The symbol it is bound to the currently iterated item (eg. for each object return current item if its age property is above 18).

 → jop --findall "it.age > 18" people.json 
[{"name":"Andrea","age":19},{"name":"Beatrice", "age": 21}]

Others accept as parameter a property name (eg. collect values for the age property) or a number (eg. display the first two items of the input collection):

 → jop --collect "name" people.json 
[ "Andrea", "Beatrice", "Carlo" ]

 → jop --head 2 people.json 
[{"name":"Andrea","age":19},{"name":"Beatrice", "age": 21}]

The output of one operation is used as input by the next one (eg. collect names for people older than 18):

 → jop --findall "it.age > 18" --collect "name" people.json 
[ "Andrea", "Beatrice" ]

One of the most remarkable feature of jop is the ability to use a javascript expression to transform JSON structure in input creating a brand new collection of objects,

 → jop -t "out[key] = { name: it.name, yob: new Date().getFullYear() - it.age }" -p people.json
[
  {
    "name": "Andrea",
    "age": 19,
    "yob": 1995
  },
  {
    "name": "Beatrice",
    "age": 21,
    "yob": 1993
  },
  {
    "name": "Carlo",
    "age": 16,
    "yob": 1998
  }
]

or appending properties to the existing ones

 → jop -t "out[key] = _.merge( _.mapValues(it), {yob: (new Date().getFullYear() - it.age)} )" -p people.json
[
  {
    "name": "Andrea",
    "age": 19,
    "yob": 1995
  },
  {
    "name": "Beatrice",
    "age": 21,
    "yob": 1993
  },
  {
    "name": "Carlo",
    "age": 16,
    "yob": 1998
  }
]

The example above shows how to access, in the expression context, to the:

  • output object via the out
  • current object key via the key
  • Lo-Dash library methods via _

Motivation

I am a fan of command line tools. In many situations I would have wished something like grep or awk to manipulate JSON content. I tried jq, which seems very good. However I was not quite able to grasp its syntax, so I gave up searching and I created my own.

At first I implemented the tool in Groovy. Results were quite interesting: Groovy has an amazing support for handling JSON, moreover the expressiveness of the Groovy syntax comes quite handy while writing node manipulation expressions. However JVM slow startup time is a big issue for a commandline tool like jop. So I re-engineered the tool using node.js.

Installation and usage

For both install informations and an extensive list of examples, please refer to the project page on Github.

Feel free to contribute with pull requests and/or submitting bugs.