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