gron and ungron: Grep JSON, Then Reassemble
gron rewrites JSON as one discrete assignment per line so grep can find a deep value by path, and ungron turns those lines back into JSON.
jq is powerful but its path syntax is another language. gron makes JSON greppable: every leaf becomes json.a.b[0] = "x";, so you locate and edit values with the grep and sed you already know. This page covers the grep+edit workflow; the base reference is gron-greppable-json.
What it does
gron reads JSON and prints a flat list of absolute-path assignments, one per line. Piping those lines through grep narrows to the paths you care about, and gron -u (ungron) reassembles a set of assignment lines back into valid JSON, so you can round-trip an edit.
Common usage
curl -s https://api.example.com | gron | grep 'version'
# find, edit with sed, then reassemble
gron config.json | grep -v 'debug' | gron -u
gron config.json | sed 's/"dev"/"prod"/' | gron -u > out.jsonOptions
| Flag | What it does |
|---|---|
| -u, --ungron | Reverse: turn assignment lines back into JSON |
| -s, --stream | Treat input as a stream of JSON objects |
| -j, --json | Represent the output itself as JSON statements |
| -c, --colorize | Force colorized output |
In CI
The gron / grep / ungron loop is the simplest safe way to make a targeted edit to a JSON file in a script: grep to the lines, transform with sed, and gron -u to rebuild valid JSON. Because grep works on absolute paths, grep '\.version =' finds a field wherever it sits, which is handy for auditing config across many files.
Common errors in CI
"gron: failed to form statements: ..." (or a JSON parse error) means the input was not valid JSON, often a truncated curl or an error body; validate first. ungron fails to reassemble if you removed lines that leave a dangling array index or an inconsistent path, so keep whole subtrees together when filtering. Mixing keys from different documents into one ungron run produces merged, likely wrong, JSON.