Overview
JSON is an excellent data interchange format and rapidly becoming the preferred format for Web APIs. Thusfar, most of the tools to process it are very limited. Yet, when working in JavaScript, JSON is fluid and natural.
Why can't command-line JavaScript be easy?
Underscore-CLI can be a simple pretty printer:
cat data.json | underscore print --color
Or it can form the backbone of a rich, full-powered JavaScript command-line, inspired by "perl -pe", and doing for structured data what sed, awk, and grep do for text.
cat example-data/earthporn.json | underscore extract 'data.children' | underscore pluck data | underscore pluck title
See Real World Example for the output and more examples.
Underscore-CLI is:
- FLEXIBLE - THE "Swiss Army knife" tool for processing JSON data - can be used as a simple pretty-printer, or as a full-powered JavaScript command-line
- POWERFUL - Exposes the full power and functionality of [underscore.js] (http://documentcloud.github.com/underscore/) (plus [underscore.string] (https://github.com/epeli/underscore.string), json:select, and CoffeeScript)
- SIMPLE - Makes it simple to write JavaScript one-liners similar to using "perl -pe"
- CHAINED - Multiple command invokations can be chained together to create a data processing pipeline
- MULTI-FORMAT - Rich support for input / output formats - pretty-printing, strict JSON, etc. See [Data Formats] (#data_formats)
- DOCUMENTED - Excellent command-line documentation with multiple examples for every command
A Bit More Explanation ...
Underscore-CLI is built on Node.js, which is less than a 4M download and very easy to install. Node.js is rapidly gaining mindshare as a tool for writing scalable services in JavaScript.
Unfortutately, out-of-the-box, Node.js is a pretty horrible as a command-line tool. This is what it takes to simply echo stdin:
cat foo.json | node -e '
var data = "";
process.stdin.setEncoding("utf8");
process.stdin.on("data", function (d) {
data = data + d;
});
process.stdin.on("end", function () {
// put all your code here
console.log(data);
});
process.stdin.resume();
'
Ugly. Underscore-CLI handles all the verbose boilerplate, making it easy to do simple data manipulations:
echo '[1, 2, 3, 4]' | underscore process 'map(data, function (value) { return value+1 })'
If you are used to seeing "_.map", note that because we arn't worried about keeping the global namespace clean, many useful functions (including all of underscore.js) are exposed as globals.
Of course 'mapping' a function to a dataset is super common, so as a shortcut, it's exposed as a first-class command, and the expression you provide is auto-wrapped in "function (value, key, list) { return ... }".
echo '[1, 2, 3, 4]' | underscore map 'value+1'
Also, while you can pipe data in, if the data is just a string like the example above, there's a shortcut for that too:
underscore -d '[1, 2, 3, 4]' map 'value+1'
Or if it's stored in a file, and you want to write the output to another file:
underscore -i data.json map 'value+1' -o output.json
Here's what it takes to increment the minor version number for an NPM package (straight from our Makefile):
underscore -i package.json process 'vv=data.version.split("."),vv[2]++,data.version=vv.join("."),data' -o package.json
Installing Underscore-CLI
Installing Node.js (command-line JavaScript)
Installing Node.js is easy. It's only a 4M download:
Alternatively, if you do homebrew, you can:
brew install node
For more details on what Node.js is, see this StackOverflow question
Installing
npm install -g underscore-cli
underscore help
Documentation
.
Usage
If you run the tool without any arguments, this is what prints out: