Created
November 23, 2011 16:48
-
-
Save devdazed/1389183 to your computer and use it in GitHub Desktop.
JSON Field Grep in Node.JS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 binaryUsage: