jq 'walk(if type == "array" then (if length > 0 then [.[0]] else . end) else . end)'
So that 70,000+ line Amazon example of yours would boil down to: {
"syncToken": "1753114994",
"createDate": "2025-07-21-16-23-14",
"prefixes": [
{
"ip_prefix": "3.4.12.4/32",
"region": "eu-west-1",
"service": "AMAZON",
"network_border_group": "eu-west-1"
}
],
"ipv6_prefixes": [
{
"ipv6_prefix": "2600:1f69:7400::/40",
"region": "mx-central-1",
"service": "AMAZON",
"network_border_group": "mx-central-1"
}
]
}
.. which is easier/cheaper to feed to an LLM for getting it to write code to process, etc. than the multi-megabyte original.
I'm a big fan of jq, having written my own jq wrapper that supports multiple formats (github.com/jzelinskie/faq), but these days I find myself more quickly reaching for Python when I get any amount of complexity. Being able to use uv scripts in Python has considerably lowered the bar for me to use it for scripting.
Where are you drawing the line?
But as an example of about where I'd stop using jq/shell scripting and switch to an actual program... we have a service that has task queues. The number of queues for an endpoint is variable, but enumerable via `GET /queues` (I'm simplifying here of course), which returns e.g. `[0, 1, 2]`. There was a bug where certain tasks would get stuck in a non-terminal state, blocking one of those queues. So, I wanted a simple little snippet to find, for each queue, (1) which task is currently executing and (2) how many tasks are enqueued. It ended up vaguely looking like:
which ends up producing output like (assuming queue 0 was blocked) I think this is roughly where I'd start to consider "hmm, maybe a proper script would do this better". I bet the equivalent Python is much easier to read and probably not much longer.Although, I think this example demonstrates how I typically use jq, which is like a little multitool. I don't usually write really complicated jq.