1# Advanced Usage
2
3Although gron's primary purpose is API discovery, when combined with other tools like `grep` it can do some interesting things.
4
5As an exercise, let's try to mimick some of the examples from the [jq tutorial](https://stedolan.github.io/jq/tutorial/).
6
7> Disclaimer: munging data on the command line with gron can be useful, but using tools like `grep` and `sed` to manipulate the
8> data is error-prone and shouldn't be relied on in scripts.
9
10Get the last 5 commits from the gron repo:
11```
12▶ gron "https://api.github.com/repos/tomnomnom/gron/commits?per_page=5"
13json = [];
14json[0] = {};
15json[0].author = {};
16json[0].author.avatar_url = "https://avatars.githubusercontent.com/u/58276?v=3";
17json[0].author.events_url = "https://api.github.com/users/tomnomnom/events{/privacy}";
18...
19json[4].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/cbcad2299e55c28a9922776e58b2a0b5a0f05016";
20json[4].parents[0].sha = "cbcad2299e55c28a9922776e58b2a0b5a0f05016";
21json[4].parents[0].url = "https://api.github.com/repos/tomnomnom/gron/commits/cbcad2299e55c28a9922776e58b2a0b5a0f05016";
22json[4].sha = "91b204972e63a1166c9d148fbbfd839f8697f91b";
23json[4].url = "https://api.github.com/repos/tomnomnom/gron/commits/91b204972e63a1166c9d148fbbfd839f8697f91b";
24```
25
26To make the rest of this a little more readable, let's add an alias for that:
27
28```
29▶ alias ggh='gron "https://api.github.com/repos/tomnomnom/gron/commits?per_page=5"'
30```
31
32Extract just the first commit using `fgrep "json[0]"`:
33```
34▶ ggh | fgrep "json[0]"
35json[0] = {};
36json[0].author = {};
37json[0].author.avatar_url = "https://avatars.githubusercontent.com/u/58276?v=3";
38json[0].author.events_url = "https://api.github.com/users/tomnomnom/events{/privacy}";
39json[0].author.followers_url = "https://api.github.com/users/tomnomnom/followers";
40...
41json[0].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311";
42json[0].parents[0].sha = "48aba5325ece087ae24ab72684851cbe77ce8311";
43json[0].parents[0].url = "https://api.github.com/repos/tomnomnom/gron/commits/48aba5325ece087ae24ab72684851cbe77ce8311";
44json[0].sha = "7da81e29c27241c0a5c2e5d083ddebcfcc525908";
45json[0].url = "https://api.github.com/repos/tomnomnom/gron/commits/7da81e29c27241c0a5c2e5d083ddebcfcc525908";
46```
47
48Get just the committer's name and the commit message using `egrep "(committer.name|commit.message)"`:
49```
50▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)"
51json[0].commit.committer.name = "Tom Hudson";
52json[0].commit.message = "Adds 0.1.7 to changelog";
53```
54
55Turn the result back into JSON using `gron --ungron`:
56```
57▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)" | gron --ungron
58[
59  {
60    "commit": {
61      "committer": {
62        "name": "Tom Hudson"
63      },
64      "message": "Adds 0.1.7 to changelog"
65    }
66  }
67]
68```
69
70gron preserves the location of values in the JSON, but you can use `sed` to remove keys from the path:
71```
72▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)" | sed -r "s/(commit|committer)\.//g"
73json[0].name = "Tom Hudson";
74json[0].message = "Adds 0.1.7 to changelog"
75
76```
77
78With those keys removed, the result is a 'flattened' object, which looks much cleaner when turned
79back into JSON with `gron --ungron`:
80
81```
82▶ ggh | fgrep "json[0]" | egrep "(committer.name|commit.message)" | sed -r "s/(commit|committer)\.//g" | gron --ungron
83[
84  {
85    "message": "Adds 0.1.7 to changelog",
86    "name": "Tom Hudson"
87  }
88]
89```
90
91Removing the `fgrep "json[0]"` from the pipeline means we do the same for all commits:
92```
93▶ ggh | egrep "(committer.name|commit.message)" | sed -r "s/(commit|committer)\.//g" | gron --ungron
94[
95  {
96    "message": "Adds 0.1.7 to changelog",
97    "name": "Tom Hudson"
98  },
99  {
100    "message": "Refactors natural sort to actualy work + be more readable",
101    "name": "Tom Hudson"
102  },
103...
104```
105
106To 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`:
107```
108▶ ggh | egrep "(committer.name|commit.message|parents.*html_url)" | sed -r "s/(commit|committer)\.//g"
109json[0].name = "Tom Hudson";
110json[0].message = "Adds 0.1.7 to changelog";
111json[0].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311";
112json[1].name = "Tom Hudson";
113json[1].message = "Refactors natural sort to actualy work + be more readable";
114json[1].parents[0].html_url = "https://github.com/tomnomnom/gron/commit/3eca8bf5e07151f077cebf0d942c1fa8bc51e8f2";
115...
116```
117
118To 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:
119```
120▶ ggh | egrep "(committer.name|commit.message|parents.*html_url)" | sed -r "s/(commit|committer)\.//g" | sed -r "s/\.html_url//"
121json[0].name = "Tom Hudson";
122json[0].message = "Adds 0.1.7 to changelog";
123json[0].parents[0] = "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311";
124json[1].name = "Tom Hudson";
125json[1].message = "Refactors natural sort to actualy work + be more readable";
126json[1].parents[0] = "https://github.com/tomnomnom/gron/commit/3eca8bf5e07151f077cebf0d942c1fa8bc51e8f2";
127...
128```
129
130And, of course, the statements can be turned back into JSON with `gron --ungron`:
131```
132▶ ggh | egrep "(committer.name|commit.message|parents.*html_url)" | sed -r "s/(commit|committer)\.//g" | sed -r "s/\.html_url//" | gron --ungron
133[
134  {
135    "message": "Adds 0.1.7 to changelog",
136    "name": "Tom Hudson",
137    "parents": [
138      "https://github.com/tomnomnom/gron/commit/48aba5325ece087ae24ab72684851cbe77ce8311"
139    ]
140  },
141  {
142    "message": "Refactors natural sort to actualy work + be more readable",
143    "name": "Tom Hudson",
144    "parents": [
145      "https://github.com/tomnomnom/gron/commit/3eca8bf5e07151f077cebf0d942c1fa8bc51e8f2"
146    ]
147  },
148...
149```
150