JJ: JSON Stream Editor
github.com
github.com
A group of motivated users are currently talking about what direction to take; a fork is being considered in order to unlock new development and bug fixes [3]. Maybe someone reading this is able and willing to join their efforts.
[1]: https://github.com/stedolan/jq/issues/2305
For me it's kind of done. It could be faster, but then I tend to program a solution myself instead, otherwise I feel like it's Done Enough.
AFAIK there’s quite a few bug fixes and features that are accumulated on the unreleased main branch, or opened as PRs but never merged.
IIRC I hit one of the bugs while trying to check whether an input document is valid JSON.
I should try checking out what’s happening to the fork, I’ve never opened a PR or something but I’ve read the source while trying to understand the jq language conceptually, and I’d say it’s quite elegant :)
jq on Windows produces \r\n terminated lines which can be annoying when used with Cygwin / MSYS2 / WSL. The '--binary' option to not convert line delimiters is one of those pending improvements.
https://github.com/stedolan/jq/commit/0dab2b18d73e561f511801...
I mean it would be understandable if the maintainers didn't have the time to keep working on it at all, but clearly the review work was done to accept some patches so why not make .point releases to allow the fixed code reach users via their distribution's channels?
A decaffinated sloth could be faster.
He seems to be working at Jane Street though, so if anyone is able to reach him please help the jq community :)
https://signals-threads.simplecast.com/episodes/memory-manag...
Other than that I can't think of a reason to use this over jq; the query language is perhaps a bit more forgiving in some ways, but not as expressive as jq (and I've spent ~8 years getting pretty familiar with jq's quirks)
Followed closely by figuring out the path to the area of data I'm interested in. "gron" has been a real time saver there - it converts the json into single lines of key/value - so you can use grep and find the full path for any string.
Switching to a GUI to browse the JSON that would let you copy the path to the current value would probably also help there, but, I'm usually in the terminal doing a bunch of different tasks looking through all manor of command outputs, logs, etc :)
Relatedly my primary use of ChatGPT has been asking it to write jq queries for me, it's not too bad at getting close. It's biggest blindness seems to be string values with a dash, which you have to write as ["key-name"].
Nonetheless, it is pretty slow at processing data. For example, converting a 1 GB JSON array of objects to JSON Lines takes ages, if it works at all. Using the steaming features helps, but they are hard to comprehend. It gets memory consumption under control and doesn't take super long, but still way too long for such a trivial task IMO.
Try https://jless.io/ then.
I use an app called OK JSON on the mac for this. Its okay.
There might be a nice 'edit just this path in-place in gron-style' recipe to be had out of jj/jq + gron together...
For example, I frequently use jq for queries like this:
jq '.data | map(select(.age <= 25))' input.json
Or this: jq '.data | map(.country) | sort[]' input.json | uniq -c
Is it possible to do something similar with this tool?This is not a slight at jj. Even if it's more limited than jq, it's still of great value if it means it's faster or more ergonomic for a subset of cases. I'm just trying to understand how it fits in my toolbox.
jj 'data.#(age<=25)#' -i input.json
I don't think there is a way to sort an array, though. However, there is an option to have keys sorted. Personally, I don't think there is much annoyance in that. One could just pipe jj output to `sort | uniq -c`.I just discovered that gjson supports custom modifiers [1]. So technically, you could fork jj, and add another file registering `@sort` modifier via `gjson.AddModifier` and have a custom jj version supporting sorting.
[0]: https://github.com/tidwall/gjson/blob/master/SYNTAX.md
[1]: https://github.com/tidwall/gjson/blob/master/SYNTAX.md#modif...
This program could be an alternative to jq for simple uses.
However, jsonptr is even faster and also runs in a self-imposed SECCOMP_MODE_STRICT sandbox (very secure; also implies no dynamically allocated memory).
$ time cat citylots.json | jq -cM .features[10000].properties.LOT_NUM
"091"
real 0m4.844s
$ time cat citylots.json | jj -r features.10000.properties.LOT_NUM
"091"
real 0m0.210s
$ time cat citylots.json | jsonptr -q=/features/10000/properties/LOT_NUM
"091"
real 0m0.040s
jsonptr's query format is RFC 6901 (JSON Pointer). More details are at
https://nigeltao.github.io/blog/2020/jsonptr.htmlIf you just want the jsonptr program, instead of everything in the repo (the Wuffs compiler (written in Go), the Wuffs standard library (written in Wuffs), tests and benchmarks (written in C/C++), etc) then you can use "build-example.sh" instead of "build-all.sh".
./build-example.sh example/jsonptr
For example/jsonptr, that should work "out of the box", with no dependencies required (other than a C++ compiler). For e.g. example/sdl-imageviewer, you'll also need the SDL library.Alternatively, you could just invoke g++ directly, as described at the very top of the "More details are at [link]" page in the grand-parent comment.
$ git clone https://github.com/google/wuffs.git
$ g++ -O3 -Wall wuffs/example/jsonptr/jsonptr.cc -o my-jsonptrJust wanted to drop a quick note to say how much I'm loving jj. This tool is seriously a game-changer for dealing with JSON from the command line. It's super easy to use and the syntax is a no-brainer.
The fact that jj is a single binary with no dependencies is just the cherry on top. It's so handy to be able to take it with me wherever I go and plug it into whatever I'm working on.
And props to you for the docs - they're really well put together and made it a breeze to get up and running.
Keep up the awesome work! Can't wait to see where you take jj next.
Cheers
$ echo '{"name":{"first":"Tom","middle":"null","last":"Smith"}}' | jj name.middle
null
$ echo '{"name":{"first":"Tom","last":"Smith"}}' | jj name.middle
null
It can be avoided with option '-r' which should be the default, but is not.
edit:
There are three cases to cover:
1. The value at the path exists and not null.
2. The value at the path exists and is null.
3. The value at the path doesn't exist.
jj seems to potentially confuse 1 and 2 without the -r flag. "middle": "null" and "middle": null more specifically. It probably confuses "middle": "" and missing value as well, that's 1 and 3.
In those cases, querying un-indexed files seems quite a thinko. Even if you can fit it all in RAM.
If you only scan that monstrous file sequentially, then you don't need either jq or jj or any other "powerful" tool. Just read/write it sequentially.
If you need to make complex scans and queries, I suspect a database is better suited.
Databases are not used in this case because it’s a complexity overhead compared to plain-text files. The ability to use unix pipelines and tools (such as grep) is a bonus.
{"a":1,"b":[true,false,null,"str"],"c":{"d":4,"e":5}}
jshon [actions] < sample.json
jshon -e c -> {"d":4,"e":5}
jshon -e c -e d -u -p -e e -u -> 4 5
Yet this covers like ~50% of possible use cases for jq.