Jq – Work with JSON on the command line
200ok.ch
200ok.ch
The links to the project aren't immediately obvious, so here they are:
Is there any way that you could allow for the minify and format commands to be accessible from the in-GUI command-line?
Not limited to JSON, and super fast.
~> curl -s http://httpbin.org/ip | rq
{
"origin": "184.100.112.11"
}
~> curl -s http://httpbin.org/ip | rq 'at origin'
"184.100.112.11"
~> curl -s http://httpbin.org/ip | rq 'at origin | split "." | spread | drop 3'
"11"
~> curl -s http://httpbin.org/ip | rq -C
?foriginn184.100.112.11⏎
(These are a bit contrived, but that was the only public API that returns JSON I could think of.)The only thing I haven't figured out is how to unquote string elements once filtered down to just that string.
Feel free to submit a feature request about the raw string use-case, I've been thinking about it for a while but some people have wanted me to add line support (maybe -l and -L?) and some people have wanted raw text support (maybe -r and -R?) while other people still have been talking about TSV/CSV support (not sure how that would look tbh...). I'm not sure what to do exactly, so feel free to tell me!
http://www.compciv.org/recipes/data/touring-the-spotify-api/
(just noticed that you used the Spotify API too for the demo :) https://github.com/dflemstr/rq/blob/master/doc/demo.md)
I personally like using jq but not sure how easy-to-grok it is for people who are new to both the command-line and to serialized data structures in general. Will have give rq a spin (waiting for it to compile on my machine) but it looks quite nice, at least for my own uses, which heavily involve YAML.
In terms of TSV/CSV support, you may want to checkout csvjson, which is part of the csvkit command-line suite: http://csvkit.readthedocs.io/en/0.9.1/scripts/csvjson.html
csvkit is my go-to tool for data, so much that I rarely ever use SQL for anything other than when I actually need a database. I suppose if rq were to be my go-to data-processing tool, I'd probably do this:
csvjson mydata.csv | rq ...
Unless I'm missing it in the documents, there doesn't appear to be a way to convert to CSV? That would be helpful. FWIW, csvkit has a tool named in2csv, which will read from line-delimited JSON: curl -s 'https://api.spotify.com/v1/search?q=rihanna&type=track&limit=50' \
| rq 'at "tracks.items" | spread | flatMap artists' \
| in2csv -f ndjson
http://csvkit.readthedocs.io/en/stable/scripts/in2csv.htmlQuick check whether it is super fast for a simple task like extracting a single field from 1M JSON objects:
$ time rq -j 'at "title"' < fixtures/1m.ldj > /dev/null real 2m16.692s
$ time jq .title < fixtures/1m.ldj > /dev/null real 0m26.040s
So jq is 8 times faster? Anyway, rq functions look useful, so will definitely check it out.
That v8 crate looks interesting. There was a post a while back about Neon, for writing Node modules in Rust:
jq & jo are the Calvin & Hobbes of the shell: lots of fun together!
A few examples:
- Generate a simple JSON object:
$ jo foo=12 bar=true baz=null
{"foo":12,"bar":true,"baz":"null"}
- Want a nested object? $ jo foo=12 bar=true baz=null thing=$(jo number=57 test=string)
{"foo":12,"bar":true,"baz":"null","thing":{"number":57,"test":"string"}}
- What about arrays? $ jo thing=$(jo number=57 test=string) anarray=$(jo -a 1 2 3 4 5)
{"thing":{"number":57,"test":"string"},"anarray":[1,2,3,4,5]}
- Now let's add some jq magic to sum all the values in the array together: $ jo thing=$(jo number=57 test=string) anarray=$(jo -a 1 2 3 4 5) | jq '.anarray | add'
15
Great stuff :)2 years ago:
https://news.ycombinator.com/item?id=9446980 (91 comments)
https://news.ycombinator.com/item?id=7895076 (55 comments)
4 years ago:
https://news.ycombinator.com/item?id=4679933 (36 comments)
https://news.ycombinator.com/item?id=4985250 (10 comments)
https://news.ycombinator.com/item?id=5734683 (29 comments)
PS C:\> $x = ConvertFrom-Json -InputObject '[{"banana" : {"stem" : "brown", "peel" : "yellow", "flesh" : "white"}}]'
PS C:\> $x.banana.peel
yellow
"yellow"
PS C:\> $x = [XML]"<banana><stem>brown</stem><peel>yellow</peel><flesh>white</flesh></banana>"
PS C:\> $x.banana.peel
yellow
PS C:\> $x = ConvertFrom-Json -InputObject '[{"banana" : {"stem" : "brown", "peel" : "yellow", "flesh" : "white"}}]'
PS C:\> $x.banana.peel
yellow
PS C:\> $x = New-Object PSObject -Property @{banana = New-Object PSObject -Property @{stem = "brown"; peel = "yellow"; flesh = "white"}}
PS C:\> $x.banana.peel
yellow
PS C:\> $x = @{banana = @{stem = "brown"; peel = "yellow"; flesh = "white"}}
PS C:\> $x.banana.peel
yellow
Specifically, if I have something that output objects, it is possible (and likely) that I can not persist that output to less and explore what is going on. Great if I already know exactly what I want. Terrible if I just want a visual exploration. Worse, if I can't dump it to file, I may have to constantly do some expensive operations just to find out what will give me the answer I want.
Or is there some OO shell that works on Mac or Linux that I don't know about?
To pretty print JSON:
cat myjson.json | python -m json.tool > prettyPrinted.json
To validate json: cat myjson.json | python -m json.tool
echo $?
If the result is 0 it is well formed and 1 otherwise. You can also pretty print JSON by opening the scratchpad in firefox and clicking the "Pretty print" button.[0]: https://aws.amazon.com/cli/
[1]: http://jmespath.org/
[0]: https://github.com/Azure/azure-cli [1]: http://jmespath.org/libraries.html
function ruby_json {
ruby -e "require 'json'; require 'active_support/all'; puts JSON.parse(STDIN.read)$1"
}
Performs/prints arbitrary ruby over a readily available representation of the JSON object coming from stdin.Example:
curl the_endpoint | ruby_json "['funnels'].map{|a| puts a.to_i * 2 }"Figuring out this use case from the jq docs or jqplay has been a major struggle for me. I feel that this use case reflects 90% of what I would want to use jq for. I feel that if I can't get over this hump just from docs, there's no way I could justify bringing this tool on board with my team.
So your example would be something like: select(.request.headers|map(.[0] == "X-My-Header" and .[1] == "my target value")|any)|<pick out some keys to display>
I realise though that your point wasn't the specific example, it's that the docs for these kind of cases are poor, and you aren't wrong.
I guess my main advice is to not think of jq as something like cut or sort - instead, it's more like awk or sed. You can do lots of crazy things with sed, but it's not immediately obvious how just from reading the man page. These kinds of tools require a little more time investment but are very powerful.
(edit for code typo)
http put your.api.endpoint email=your@email.address password=swaggerrocks
HTTPie and jq go together like peanut butter and chocolate, except without the caloric bloat.https://github.com/stedolan/jq
https://github.com/ggreer/the_silver_searcher
"The command name is 33% shorter than ack!"
--output=expr
Output the evaluation of expr for each line (turns off text
highlighting) If PATTERN matches more than once then a line is
output for each non-overlapping match. For more information please
see the section "Examples of --output".
Basically, it allows you to use captured groups in the output: cat file | ag '(\w+) (\d+)' --output '$1 is $2 years old'
On the other hand, ag allows multiline matching. So I end up using ag and ack together frequently. sed -rn 's/([a-zA-Z]+) ([0-9]+)/\1 is \2 years old/p' file cat file | perl -ne 'print if s/(\w+) (\d+)/\1 is \2 years old/'
My only point is sometimes old school standard tools are plenty.1: https://www.gnu.org/software/sed/manual/sed.html#Extended-re...
But when I saw mVChr's sed line, and then again the perl line, I was reminded "Oh, right, old school." And I wondered for the Nth time how much of old school has been unknowingly reinvented, and how many times.
Nevertheless, I like the new(er) tools in this thread too.
http://jmespath.org/libraries.html
(also, a nicer language IMO, even if it has slightly fewer features)
jq is one of my favourite tools - can't recommend it enough.
$PROGRAM_THAT_OUTPUTS_JSON | jq .
Which simply pretty prints the JSON input with two spaces per indentation. Also, $PROGRAM_THAT_OUTPUTS_JSON is usually a script that simply outputs the clipboard (alias for "xclip -o"). pbpaste | jq -c '.actionResponses[].data.items[] | [.attributes[] | .stringValue // (.numberValue | tonumber)]'