gron README

The project's README from github.com/tomnomnom/gron. As one markdown file: README.md.

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 = "[email protected]";
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": "[email protected]",
        "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 = "[email protected]";
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 = "[email protected]";
---
> json.contact.email = "[email protected]";

The output of gron is valid JavaScript:

▶ gron testdata/two.json > tmp.js
▶ echo "console.log(json);" >> tmp.js
▶ nodejs tmp.js
{ contact: { email: '[email protected]', 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": "[email protected]",
    "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.

gron (tomnomnom/gron)

Searching Database…

14.5K ·GitHub
这是什么?gron 可以把 JSON 转换成一条条独立的赋值语句(每行一个路径和值),这样你就能用普通的命令行文本工具,如 grep、sed 和 diff,来查找、替换和比较 JSON。
这是命令行工具还是代码库?它是一个独立的命令行可执行文件,用 Go 语言编写,没有运行时依赖。
我怎么安装和使用它?下载适用于 Linux、Mac、Windows 或 FreeBSD 的预编译可执行文件,并将其放入 PATH 中;也可以通过 Homebrew(Mac)或 `go install` 安装。然后运行 `gron 文件名`,或通过标准输入(stdin)把 JSON 传给它。
运行它还需要额外安装别的东西吗?不需要,除了你平时已经在用的 grep、sed 等标准工具之外,它没有任何运行时依赖。
经过过滤的输出能转换回真正的 JSON 吗?可以,运行 `gron --ungron` 就能把经过 grep 过滤的赋值语句行转换回 JSON;缺失索引的数组会用 null 补齐,以保留键。
这在 Windows 和 Mac 上也能用吗,还是只能用在 Linux 上?可以,官方提供了适用于 Linux、Mac、Windows 和 FreeBSD 的可执行文件。
为什么不直接用 jq?jq 功能更强大,但需要事先了解 JSON 的结构;gron 则适合用来探索不熟悉的、嵌套很深的 JSON,你只需要使用 grep 和 sed 这些已经熟悉的工具,无需学习新的查询语言。
gron 最初就是用 Go 写的吗?不是,最初的版本是用 PHP 写的;之后用 Go 重写,主要是为了去掉 PHP 这个运行时依赖。
gron 能输出流式 JSON 吗?可以,使用 --json 参数可以把 gron 的结果输出为 JSON 流。
gron 的典型使用场景是什么?探索文档不全的 API 响应。例如,把 GitHub API 的响应通过管道传给 gron,再用 grep 搜索 commit.author 之类的字段,就能立刻看到它的完整路径。
What are similar projects?miller, fx, fq, hyperfine, hexyl, oh-my-posh, chezmoi, slides
Creator
tomnomnom
Size
1.5 MB
Stars
14.5K
Age
14y
Commits · 90 Days