Skip to content

Instantly share code, notes, and snippets.

@devdazed
Created November 23, 2011 16:48
Show Gist options
  • Save devdazed/1389183 to your computer and use it in GitHub Desktop.
Save devdazed/1389183 to your computer and use it in GitHub Desktop.
JSON Field Grep in Node.JS
#!/usr/bin/env node
var stdin = process.stdin,
fields = process.argv.slice(2),
buf = [];
if (fields.length === 0){
console.error('Usage: jgrep "some.fields in.json" < STDIN');
process.exit(1);
}
/**
* Safely resoves an object using dot notation
*
* @param {Object} obj The object to resolve
* @param {String} selector The selector in dot notation to resolve (eg. 'foo.bar.baz' )
*/
function resolve(obj, selector){
var parts = selector.split('.'),
part = parts.shift();
if(obj === undefined){
return obj;
}
if (parts.length === 0){
return obj[part];
} else {
return resolve(obj[part], parts.join('.'));
}
}
/**
* Builds the object structure to match the selector
*
* @param {Object} obj The object to build on
* @param {String} selector The selector in dot notation to resolve (eg. 'foo.bar.baz' )
*/
function build(obj, selector){
var parts = selector.split('.'),
part = parts.shift();
obj[part] = obj[part] || {};
if (parts.length > 0){
build(obj[part], parts.join('.'));
}
}
/**
* Returns only the fields specified
*
* @param {String} data The stringified JSON data
* @param {Array} fields An array of fields to return, in dot notation.
*/
function jGrep(data){
try{
data = JSON.parse(data);
var i = 0, flen = fields.length,
ret = {}, field, retfield, farr, lastfield;
for (; i < flen; i += 1){
field = fields[i];
build(ret, field);
farr = field.split('.');
lastfield = farr.pop();
if (farr.length){
retfield = resolve(ret, farr.join('.'));
} else {
retfield = ret;
}
retfield[lastfield] = resolve(data, field);
}
console.log(JSON.stringify(ret));
} catch(e){
return undefined;
}
}
/**
* Flushes the buffer to jGrep as we have a full line
*/
function flush(){
var data = buf.join('');
buf = [];
jGrep(data);
}
/**
* buffers data and flushes when appropriate
*/
function buffer(data){
if (data.indexOf('\n') > -1){
data = data.split('\n');
buf.push(data.shift());
flush();
buffer(data.join('\n'));
} else {
buf.push(data);
}
}
/**
* receives data from stdin
*/
stdin.on('data', function(data){
buffer(data.toString());
});
stdin.resume();
// vim: ft=javascript:ts=2:sw=2
@devdazed
Copy link
Author

takes stdin and greps outputs only the fields specified, each line is treated as its own json document. chmod +x it to use it as a binary

Usage:

tail -f /tmp/mylog.json | ./jgrep.js 'field.one' 'field.two' 'some.other.field' 'yay'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment