https://github.com/tomnomnom/gron Skip to content Toggle navigation Sign up * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code Explore + All features + Documentation + GitHub Skills + Blog * Solutions For + Enterprise + Teams + Startups + Education By Solution + CI/CD & Automation + DevOps + DevSecOps Resources + Learning Pathways + White papers, Ebooks, Webinars + Customer Stories + Partners * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles Repositories + Topics + Trending + Collections * Pricing Search or jump to... Search code, repositories, users, issues, pull requests... Search [ ] Clear Search syntax tips Provide feedback We read every piece of feedback, and take your input very seriously. [ ] [ ] Include my email address so I can be contacted Cancel Submit feedback Saved searches Use saved searches to filter your results more quickly Name [ ] Query [ ] To see all available qualifiers, see our documentation. Cancel Create saved search Sign in Sign up You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session. Dismiss alert {{ message }} tomnomnom / gron Public * Notifications * Fork 322 * Star 12.8k Make JSON greppable! License MIT license 12.8k stars 322 forks Activity Star Notifications * Code * Issues 44 * Pull requests 17 * Actions * Projects 0 * Wiki * Security * Insights Additional navigation options * Code * Issues * Pull requests * Actions * Projects * Wiki * Security * Insights tomnomnom/gron This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. master Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 2 branches 34 tags Code * Local * Codespaces * Clone HTTPS GitHub CLI [https://github.com/t] Use Git or checkout with SVN using the web URL. [gh repo clone tomnom] Work fast with our official CLI. Learn more about the CLI. * Open with GitHub Desktop * Download ZIP Sign In Required Please sign in to use Codespaces. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @tomnomnom tomnomnom Adds arm64 to build arch list ... 13561bd Apr 13, 2022 Adds arm64 to build arch list 13561bd Git stats * 196 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time completions Initial commit of completions for the fish shell October 1, 2018 21:01 docs Removed cname April 3, 2018 09:06 script Adds arm64 to build arch list April 13, 2022 15:23 testdata Use larger buffer when ungron August 25, 2018 03:26 .gitignore Switches windows binary package to zip July 3, 2016 01:08 .travis.yml Removes older go version from .travis.yml November 7, 2020 01:17 ADVANCED.mkd Splits key removal advanced example into two parts June 30, 2017 10:59 CHANGELOG.mkd Adds 0.5.2, 0.6.0 to CHANGELOG July 5, 2018 10:22 CONTRIBUTING.mkd Adds changelog, update contributing June 5, 2016 21:47 LICENSE Adds license, travis.yml June 4, 2016 22:49 README.mkd Adds -v/--values option; updates release script April 13, 2022 14:57 go.mod Adds -v/--values option; updates release script April 13, 2022 14:57 go.sum Adds -v/--values option; updates release script April 13, 2022 14:57 identifier.go Fixes bug with handling of empty identifier January 1, 2018 23:57 identifier_test.go Fixes bug with handling of empty identifier January 1, 2018 23:57 main.go Adds -v/--values option; updates release script April 13, 2022 14:57 main_test.go Use larger buffer when ungron August 25, 2018 03:26 original-gron.php Moves PHP version out of the way June 2, 2016 17:41 statements.go Adds JSON encoded data format May 21, 2018 23:54 statements_test.go Fixes bug with handling of empty identifier January 1, 2018 23:57 token.go simplify quoteString December 6, 2018 23:58 token_test.go Adds custom quoteString function September 17, 2016 00:23 ungron.go Adds escape sequence tracking to acceptUntilUnescaped; fixes #25 January 31, 2017 20:10 ungron_test.go Adds escape sequence tracking to acceptUntilUnescaped; fixes #25 January 31, 2017 20:10 url.go goimports February 22, 2017 17:12 url_test.go Changes url validation so its case insensitive and adds a test for it September 4, 2016 14:20 View code [ ] gron Installation Usage ungronning Get Help FAQ Wasn't this written in PHP before? Why the change to Go? Why shouldn't I just use jq? README.mkd gron Build Status Make JSON greppable! gron transforms JSON into discrete assignments to make it easier to grep 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. Installation gron has no runtime dependencies. You can just download 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 also install gron via brew: > brew install gron Or if you're a Go user you can use go install: > go install github.com/tomnomnom/gron@latest It's recommended that you alias ungron or norg (or both!) to gron --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 named ungron or norg to affect all users: gron --ungron "$@" Usage 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 from stdin: > curl -s http://headers.jsontest.com/ | gron json = {}; 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 twitter json.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 of gron is valid JavaScript: > 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 the gron output as JSON stream via the --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"] ungronning 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 with grep 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 with null when values are missing: > gron testdata/two.json | grep likes | grep -v cheese json.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 do some pretty neat tricks with gron, and then ungron the output back into JSON. Get Help > gron --help Transform JSON (from a file, URL, or stdin) into discrete assignments to make it greppable Usage: 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 information Exit Codes: 0 OK 1 Failed to open file 2 Failed to read input 3 Failed to form statements 4 Failed to fetch URL 5 Failed to parse statements 6 Failed to encode JSON Examples: 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 FAQ Wasn't this written in PHP before? Yes it was! The original version is preserved here for posterity. Why the change to Go? Mostly to remove PHP as a dependency. There's a lot of people who work with JSON who don't have PHP installed. Why shouldn't I just use jq? jq is awesome, and a lot more powerful than gron, but with that power comes complexity. gron aims to make it easier to use the tools you already know, like grep and sed. gron's primary purpose is to make it easy to find the path to a value in a deeply nested JSON blob when you don't already know the structure; much of jq's power is unlocked only once you know that structure. About Make JSON greppable! Resources Readme License MIT license Activity Stars 12.8k stars Watchers 95 watching Forks 322 forks Report repository Releases 30 v0.7.1 Latest Apr 13, 2022 + 29 releases Packages 0 No packages published Contributors 16 * @tomnomnom * @csabahenk * @jagsta * @akavel * @iamthemovie * @gummiboll * @mattn * @kseistrup * @alblue * @orivej * @cwarden * @nwidger * @saka1 * @HaraldNordgren + 2 contributors Languages * Go 91.6% * Shell 4.9% * PHP 3.5% Footer (c) 2023 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact You can't perform that action at this time.