JSON on the Command Line with Jq
shapeshed.com
shapeshed.com
E.g.:
Filtering and transforming objects by reaching a few levels deeper in them seems to be way easier to slap together in Python's list comprehensions or some functional notation. Stuff like [{ * * x, qwe: x.qwe*2} for x in a.b if x.y.z == 1].
Add nested lists to the above, and I can spend another fifteen minutes writing a one-liner (i.e. `a` is a list of objects with lists in some field).
I once had to deal with a conditional structure where a field might be one object or a list of them. Hoo boy.
Every time I want to check the number of entries my filters print out, I need to wrap them in an array. Repeat this a couple dozen times during writing a complex query. Weirdly, this is where strict structure gets in the way―and while I understand the reasoning, I feel that something could be done for such basic need. (Like, aggregate filters should be able to aggregate instead of acting on individual items? Maybe it's already in the language, but I'm not in the mood to go over the manual again.)
Variables seem to be bolted on as an afterthought, or at least the syntax doesn't exactly accommodate them. Meanwhile, they're necessary to implement some filters omitted in the language. Compare that to Lisp's simple `(let)`. IIRC the manual also says that jq has some semblance of functions, but I'm afraid to think about them with this syntax.
I like the idea a lot, but execution not so much. Frankly I'll probably end up throwing together a script in Lumo or something, that will accept Lisp expressions and feed JSON structure to them. (I'd use Fennel, but JSON has actual null while Lua... doesn't.)
Btw, I have pretty much the same sentiment about Git. Git structures, great. Git tools, oy vey. Maybe I need Lisp for Git, or at least Python for Git.
This may come off as a little snarky but, you should totally give this a try and post the result on HN.
I say this because I both love jq for its functionality, but also have deep frustrations with wrangling it. I really encourage any attempts to improve it.
There's definitely room for a better jq - I would 100% try a version of it that was as simple to install, use, and just had a slightly easier to use language.
Now, I could attempt doing this in ClojureScript, but I'll get derailed to thinking about ClojureScript's inseparable conjoinery to Clojure and JVM, even if manifested in Lumo only as inexplicable boilerplate, and that gives me depression. Also Lua's start-up is faster than even bare Node.
Hy is probably the optimal choice. There's not even much to write: I can as well just spin up Hy's repl and read JSON in it. Maybe will need a few helper functions to save me from verbosity.
I use it 1-2 times a month and always have to RTFM.
You might like fx [0]. Run on its own, it’s a command line JSON browser (you can even click on items to expand/collapse them), and you can also write little JS one-liners to do stuff like map over an array and transform the items.
Something like this, to extract the name from an array of users, for instance:
fx users.json ‘u => u.name’
And perhaps more importantly it doesn't mess with your numbers! Some other comment mentioned doubles, but I had a problem with Longs, jq would silently truncate them when they became to large to fit inside a float (I was working with random Long numbers used as secrets in some schema so it happened quite quickly in my use case).
Thanks for the inspiration!
2015: https://news.ycombinator.com/item?id=9446980
2014: https://news.ycombinator.com/item?id=7895076
2013: https://news.ycombinator.com/item?id=5734683
2012: https://news.ycombinator.com/item?id=4985250
https://news.ycombinator.com/item?id=4679933
(for the curious)
The main issue I've run into so far is that my JSON parser can generate quite heavy in-memory representations of parsed data. It's far from optimized though, and a lot can be done before needing to worry about the limitations of the format itself. :)
JSON is ubiquitous now. So much so that even my <conservative enterprise customers>, who 20 years preferred data in CSV, 10 years ago preferred XML, now want to exchange data in JSON.
It's not perfect - it doesn't have higher-order features like types/schemas or functions built in. But JSON + jq is a workhorse. I agree that distros do people a disservice by not bundling jq in base (and attempting to provide JSON output for distro-specific tooling).
That said, I usually get on well with a halfway house of piping jq -c ... into eg grep or sort -u for easy processing (-c writes one json object per line, aka compact form), or selecting a few elements, putting them in an array, jq-piping into @csv, and passing -r to get raw output which I can then process with awk or sort or other Unix commands.
One subtle caveat is that jq normalises all the json it processes, so for example escaped characters in strings may change and numbers which are not IEEE doubles get converted (eg if someone writes a 64-bit int or a bignum as a number not a string in the json)
Does anyone know a more interactive json tool? With, for example, auto-completion? Showing possible fields to select next and maybe even possible values if fields are choosen.
https://github.com/antonmedv/fx
It just uses JS for the query language and can be hooked in to bash completion.
Personally I don't get on with jq, because I don't feel that plinking with JSON is something that warrants memorising a bespoke language.
It has interactive mode which gives you instant feedback. I also don't need to learn a completely new API, as I'm already familiar with ramda.
Has anyone gone down the road of posix like Json pipes? Or maybe just Json bridging the gap between fully typed pipes and the string based Unix cli world?
Even just having a Json output format for the core posix apps would be good. If it had OS support, maybe you wouldn't even have to serialize to strings if both sides of the pipe happened to be compatible.
I really wish there were a much greater selection of usage examples in the manual.
I use jq to mangle get/list requests from AWS (and others) and then recursively hit each element for whatever reason. Without jq none of my workflows in this area would be remotely easy.
TLDR: Learn JQ! It is like sed and grep, but for JSON.
Unless you need some additional juice, where jq supports actually transforming the return.
Quite arguably a heavier tool, e.g. a boto3 script becomes appropriate where --query falls short.
But options are a great thing to have.
Jq is so much more capable than jmespath that I find myself using jq on the json output of AWS CLI commands more than using the built-in query option. Sure, it requires another tool, but it’a often the best tool for the job.