- Notifications
You must be signed in to change notification settings - Fork329
tomnomnom/gron
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Make JSON greppable!
gron transforms JSON into discrete assignments to make it easier togrep
for what you want and see the absolute 'path' to it.It eases the exploration of APIs that return large blobs of JSON but have terrible documentation.
▶gron "https://api.github.com/repos/tomnomnom/gron/commits?per_page=1" | fgrep "commit.author"json[0].commit.author = {};json[0].commit.author.date = "2016-07-02T10:51:21Z";json[0].commit.author.email = "mail@tomnomnom.com";json[0].commit.author.name = "Tom Hudson";
gron can work backwards too, enabling you to turn your filtered data back into JSON:
▶ gron "https://api.github.com/repos/tomnomnom/gron/commits?per_page=1" | fgrep "commit.author" |gron --ungron[ { "commit": { "author": { "date": "2016-07-02T10:51:21Z", "email": "mail@tomnomnom.com", "name": "Tom Hudson" } } }]
Disclaimer: the GitHub API has fantastic documentation, but it makes for a good example.
gron has no runtime dependencies. You can justdownload a binary for Linux, Mac, Windows or FreeBSD and run it.Put the binary in your$PATH
(e.g. in/usr/local/bin
) to make it easy to use:
▶ tar xzf gron-linux-amd64-0.1.5.tgz▶ sudo mv gron /usr/local/bin/
If you're a Mac user you can alsoinstall gron via brew:
▶ brew install gron
Or if you're a Go user you can usego install
:
▶ go install github.com/tomnomnom/gron@latest
It's recommended that you aliasungron
ornorg
(or both!) togron --ungron
. Put something like this in your shell profile (e.g. in~/.bashrc
):
alias norg="gron --ungron"alias ungron="gron --ungron"
Or you could create a shell script in your $PATH namedungron
ornorg
to affect all users:
gron --ungron "$@"
Get JSON from a file:
▶ gron testdata/two.json json = {};json.contact = {};json.contact.email = "mail@tomnomnom.com";json.contact.twitter = "@TomNomNom";json.github = "https://github.com/tomnomnom/";json.likes = [];json.likes[0] = "code";json.likes[1] = "cheese";json.likes[2] = "meat";json.name = "Tom";
From a URL:
▶ gron http://headers.jsontest.com/json = {};json.Host = "headers.jsontest.com";json["User-Agent"] = "gron/0.1";json["X-Cloud-Trace-Context"] = "6917a823919477919dbc1523584ba25d/11970839830843610056";
Or fromstdin
:
▶ curl -s http://headers.jsontest.com/ | gronjson = {};json.Accept = "*/*";json.Host = "headers.jsontest.com";json["User-Agent"] = "curl/7.43.0";json["X-Cloud-Trace-Context"] = "c70f7bf26661c67d0b9f2cde6f295319/13941186890243645147";
Grep for something and easily see the path to it:
▶ gron testdata/two.json | grep twitterjson.contact.twitter = "@TomNomNom";
gron makes diffing JSON easy too:
▶ diff <(gron two.json) <(gron two-b.json)3c3< json.contact.email = "mail@tomnomnom.com";---> json.contact.email = "contact@tomnomnom.com";
The output ofgron
is valid #"▶ gron testdata/two.json > tmp.js▶ echo "console.log(json);" >> tmp.js▶ nodejs tmp.js{ contact: { email: 'mail@tomnomnom.com', twitter: '@TomNomNom' }, github: 'https://github.com/tomnomnom/', likes: [ 'code', 'cheese', 'meat' ], name: 'Tom' }">
▶ gron testdata/two.json > tmp.js▶ echo "console.log(json);" >> tmp.js▶ nodejs tmp.js{ contact: { email: 'mail@tomnomnom.com', twitter: '@TomNomNom' }, github: 'https://github.com/tomnomnom/', likes: [ 'code', 'cheese', 'meat' ], name: 'Tom' }
It's also possible to obtain thegron
output as JSON stream viathe--json
switch:
▶ curl -s http://headers.jsontest.com/ | gron --json[[],{}][["Accept"],"*/*"][["Host"],"headers.jsontest.com"][["User-Agent"],"curl/7.43.0"][["X-Cloud-Trace-Context"],"c70f7bf26661c67d0b9f2cde6f295319/13941186890243645147"]
gron can also turn its output back into JSON:
▶ gron testdata/two.json | gron -u{ "contact": { "email": "mail@tomnomnom.com", "twitter": "@TomNomNom" }, "github": "https://github.com/tomnomnom/", "likes": [ "code", "cheese", "meat" ], "name": "Tom"}
This means you use can use gron withgrep
and other tools to modify JSON:
▶ gron testdata/two.json | grep likes | gron --ungron{ "likes": [ "code", "cheese", "meat" ]}
or
▶ gron --json testdata/two.json | grep likes | gron --json --ungron{ "likes": [ "code", "cheese", "meat" ]}
To preserve array keys, arrays are padded withnull
when values are missing:
▶ gron testdata/two.json | grep likes | grep -v cheesejson.likes = [];json.likes[0] = "code";json.likes[2] = "meat";▶ gron testdata/two.json | grep likes | grep -v cheese | gron --ungron{ "likes": [ "code", null, "meat" ]}
If you get creative you can dosome pretty neat tricks with gron, andthen ungron the output back into JSON.
▶ gron --helpTransform JSON (from a file, URL, or stdin) into discrete assignments to make it greppableUsage: gron [OPTIONS] [FILE|URL|-]Options: -u, --ungron Reverse the operation (turn assignments back into JSON) -v, --values Print just the values of provided assignments -c, --colorize Colorize output (default on tty) -m, --monochrome Monochrome (don't colorize output) -s, --stream Treat each line of input as a separate JSON object -k, --insecure Disable certificate validation -j, --json Represent gron data as JSON stream --no-sort Don't sort output (faster) --version Print version informationExit Codes: 0OK 1Failed to open file 2Failed to read input 3Failed to form statements 4Failed to fetch URL 5Failed to parse statements 6Failed to encode JSONExamples: gron /tmp/apiresponse.json gron http://jsonplaceholder.typicode.com/users/1 curl -s http://jsonplaceholder.typicode.com/users/1 | gron gron http://jsonplaceholder.typicode.com/users/1 | grep company | gron --ungron
Yes it was! The original version ispreserved here for posterity.
Mostly to remove PHP as a dependency. There's a lot of people who work with JSON who don't have PHP installed.
jq isawesome, and a lot more powerful than gron, but with that power comescomplexity. gron aims to make it easier to use the tools you already know, likegrep
andsed
.
gron's primary purpose is to make it easy to find the path to a value in a deeply nested JSON blobwhen you don't already know the structure; much of jq's power is unlocked only once you know that structure.