If you’ve ever tried to read a raw API response in your terminal, you know the pain. It’s usually a giant, unreadable wall of text that makes finding a single value feel like searching for a needle in a haystack. This is exactly why I started using jq. Learning how to use jq for JSON is essentially like giving your terminal a superpower for data manipulation.
In my experience, jq is the ‘sed’ for JSON data. It allows you to slice, filter, map, and transform structured data with incredible speed. Whether you are automating a gh cli workflow automation or just debugging a local config file, jq is an indispensable tool in any developer’s kit.
Prerequisites
Before we dive into the syntax, you’ll need a few things ready:
- A Unix-like terminal (macOS, Linux, or WSL on Windows).
jqinstalled on your system. If you don’t have it, you can install it via Homebrew on Mac (brew install jq) or apt on Ubuntu (sudo apt-get install jq).- A sample JSON file. For this tutorial, I’m using a file named
data.jsonwith the following content:
[
{
"id": 1,
"name": "Project Alpha",
"status": "active",
"tags": ["automation", "cli"],
"metrics": { "cpu": 12, "ram": 512 }
},
{
"id": 2,
"name": "Project Beta",
"status": "archived",
"tags": ["legacy", "cli"],
"metrics": { "cpu": 45, "ram": 1024 }
}
]
Step-by-Step: Mastering jq Basics
1. Pretty Printing (The Basics)
The simplest way to use jq is for “pretty printing.” If you have a minified JSON file, simply passing the identity filter (the dot .) will format it for human readability.
cat data.json | jq '.'
This is the most common entry point for anyone learning how to use jq for JSON. It takes the raw stream and adds indentation and colors.
2. Accessing Properties
To grab a specific field, you use the dot notation. If your JSON is an object, .fieldname works. If it’s an array, you’ll need to iterate or index it. To get the names of all projects in our sample file:
cat data.json | jq '.[].name'
Here, .[] iterates over the array, and .name extracts the value from each object. This pattern is fundamental to modern unix commands list and data piping.
3. Filtering Data
One of the most powerful features is the select() function. Let’s say I only want projects where the status is ‘active’.
cat data.json | jq '.[] | select(.status == "active")'
As shown in the terminal output in the image below, jq filters out everything that doesn’t meet the boolean condition inside select().
4. Transforming and Mapping
Sometimes you don’t want the whole object; you just want a new structure. I often use this when preparing data for another tool. To create a simple list of project names and their RAM usage:
cat data.json | jq '.[] | {project: .name, memory: .metrics.ram}'
This creates a new JSON object for every entry in the original array, mapping .name to project and .metrics.ram to memory.
5. Advanced Slicing and Piping
You can pipe the output of one jq filter into another within the same command. For example, to get the tags of only the archived projects:
cat data.json | jq '.[] | select(.status == "archived") | .tags'
Pro Tips for CLI Efficiency
- Raw Output: Use the
-rflag to remove quotes from strings. This is critical when passingjqoutput into a shell variable. - Compact Output: Use
-cto output each object on a single line, which is ideal for processing large logs withgrep. - Combining with xargs: I frequently use
jq -r '.[] | .id' | xargs -I {} curl ...to perform bulk API actions based on JSON IDs.
Troubleshooting Common jq Issues
When I first started, I ran into these three roadblocks frequently:
| Issue | Cause | Solution |
|---|---|---|
cannot index array with string |
Trying to access a key on an array instead of an object. | Add .[] before the key name. |
Output contains quotes ("value") |
Default jq output is valid JSON. |
Use the -r (raw) flag. |
| Filter doesn’t seem to work | Incorrect nesting or pathing. | Build your filter incrementally (start with ., then .[], etc). |
What’s Next?
Now that you know how to use jq for JSON, you can start integrating it into your CI/CD pipelines or local automation scripts. If you’re looking to optimize your entire terminal experience, I highly recommend checking out my guide on modern unix commands to see what else can replace your legacy tools.
Want more automation tips? Subscribe to the newsletter or check out my latest post on GitHub CLI automation.