# Advanced Usage

Although gron's primary purpose is API discovery, when combined with other tools like `grep` it can do some interesting things.

As an exercise, let's try to mimick some of the examples from the [jq tutorial](https://stedolan.github.io/jq/tutorial/).

> Disclaimer: munging data on the command line with gron can be useful, but using tools like `grep` and `sed` to manipulate the
> data is error-prone and shouldn't be relied on in scripts.

Get the last 5 commits from the gron repo:
```
▶ gron "https://api.github.com/repos/tomnomnom/gron/commits?per_page=5"
json = [];
json[0] = {};
json[0].author = {};
json[0].author.avatar_url = "https://avatars.githubusercontent.com/u/58276?v=3";
json[0].author.events_url = "https://api.github.com/users/tomnomnom/events{/privacy}";
...
json[4].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/cbcad2299e55c28a9922776e58b2a0b5a0f05016";
json[4].parents[0].sha = "cbcad2299e55c28a9922776e58b2a0b5a0f05016";
json[4].parents[0].url = "https://api.github.com/repos/tomnomnom/gron/commits/cbcad2299e55c28a9922776e58b2a0b5a0f05016";
json[4].sha = "91b204972e63a1166c9d148fbbfd839f8697f91b";
json[4].url = "https://api.github.com/repos/tomnomnom/gron/commits/91b204972e63a1166c9d148fbbfd839f8697f91b";
```

To make the rest of this a little more readable, let's add an alias for that:

```
▶ alias ggh='gron "https://api.github.com/repos/tomnomnom/gron/commits?per_page=5"'
```

Extract just the first commit using `fgrep "json[0]"`:
```
▶ ggh | fgrep "json[0]"
json[0] = {};
json[0].author = {};
json[0].author.avatar_url = "https://avatars.githubusercontent.com/u/58276?v=3";
json[0].author.events_url = "https://api.github.com/users/tomnomnom/events{/privacy}";
json[0].author.followers_url = "https://api.github.com/users/tomnomnom/followers";
...
json[0].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311";
json[0].parents[0].sha = "48aba5325ece087ae24ab72684851cbe77ce8311";
json[0].parents[0].url = "https://api.github.com/repos/tomnomnom/gron/commits/48aba5325ece087ae24ab72684851cbe77ce8311";
json[0].sha = "7da81e29c27241c0a5c2e5d083ddebcfcc525908";
json[0].url = "https://api.github.com/repos/tomnomnom/gron/commits/7da81e29c27241c0a5c2e5d083ddebcfcc525908";
```

Get just the committer's name and the commit message using `egrep "(committer.name|commit.message)"`:
```
▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)"
json[0].commit.committer.name = "Tom Hudson";
json[0].commit.message = "Adds 0.1.7 to changelog";
```

Turn the result back into JSON using `gron --ungron`:
```
▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)" | gron --ungron
[
  {
    "commit": {
      "committer": {
        "name": "Tom Hudson"
      },
      "message": "Adds 0.1.7 to changelog"
    }
  }
]
```

gron preserves the location of values in the JSON, but you can use `sed` to remove keys from the path:
```
▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)" | sed -r "s/(commit|committer)\.//g"
json[0].name = "Tom Hudson";
json[0].message = "Adds 0.1.7 to changelog"

```

With those keys removed, the result is a 'flattened' object, which looks much cleaner when turned
back into JSON with `gron --ungron`:

```
▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)" | sed -r "s/(commit|committer)\.//g" | gron --ungron
[
  {
    "message": "Adds 0.1.7 to changelog",
    "name": "Tom Hudson"
  }
]
```

Removing the `fgrep "json[0]"` from the pipeline means we do the same for all commits:
```
▶ ggh | egrep "(committer.name|commit.message)" | sed -r "s/(commit|committer)\.//g" | gron --ungron
[
  {
    "message": "Adds 0.1.7 to changelog",
    "name": "Tom Hudson"
  },
  {
    "message": "Refactors natural sort to actualy work + be more readable",
    "name": "Tom Hudson"
  },
...
```

To include the `html_url` key for each commit's parents, all we need to do is add `parents.*html_url` into our call to `egrep`:
```
▶ ggh | egrep "(committer.name|commit.message|parents.*html_url)" | sed -r "s/(commit|committer)\.//g"
json[0].name = "Tom Hudson";
json[0].message = "Adds 0.1.7 to changelog";
json[0].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311";
json[1].name = "Tom Hudson";
json[1].message = "Refactors natural sort to actualy work + be more readable";
json[1].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/3eca8bf5e07151f077cebf0d942c1fa8bc51e8f2";
...
```

To make the structure more like that in the final example in the `jq` tutorial, we can use `sed -r "s/\.html_url//"` to remove the `.html_url` part of the path:
```
▶ ggh | egrep "(committer.name|commit.message|parents.*html_url)" | sed -r "s/(commit|committer)\.//g" | sed -r "s/\.html_url//"
json[0].name = "Tom Hudson";
json[0].message = "Adds 0.1.7 to changelog";
json[0].parents[0] = "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311";
json[1].name = "Tom Hudson";
json[1].message = "Refactors natural sort to actualy work + be more readable";
json[1].parents[0] = "https://github.com/tomnomnom/gron/commit/3eca8bf5e07151f077cebf0d942c1fa8bc51e8f2";
...
```

And, of course, the statements can be turned back into JSON with `gron --ungron`:
```
▶ ggh | egrep "(committer.name|commit.message|parents.*html_url)" | sed -r "s/(commit|committer)\.//g" | sed -r "s/\.html_url//" | gron --ungron
[
  {
    "message": "Adds 0.1.7 to changelog",
    "name": "Tom Hudson",
    "parents": [
      "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311"
    ]
  },
  {
    "message": "Refactors natural sort to actualy work + be more readable",
    "name": "Tom Hudson",
    "parents": [
      "https://github.com/tomnomnom/gron/commit/3eca8bf5e07151f077cebf0d942c1fa8bc51e8f2"
    ]
  },
...
```
