As developers and sysadmins, we often deal with commands that return JSON output. Tools like curl, kubectl, aws, or even custom scripts output JSON, but reading it directly in the terminal is cumbersome. Enter jq: a lightweight, flexible command-line JSON processor. In this tutorial, we’ll explore how to harness jq for querying, formatting, and manipulating JSON directly from Bash.
What is jq?
jq is a command-line utility for parsing and transforming JSON data. Think of it as sed or awk for JSON: you can filter, extract, transform, and even generate JSON easily.
Installation:
On Linux (Debian/Ubuntu):
sudo apt update sudo apt install jq -y
On macOS (with Homebrew):
brew install jq
Check your installation:
jq --version
Basic Usage
Assume you have a JSON file called data.json:
{
"users": [
{ "id": 1, "name": "Alice", "role": "admin" },
{ "id": 2, "name": "Bob", "role": "user" },
{ "id": 3, "name": "Charlie", "role": "user" }
]
}
1. Pretty-print JSON
JSON output from commands is often minified. Use jq to make it readable:
cat data.json | jq
Or directly:
jq '.' data.json
The . filter selects the entire JSON structure.
2. Access Specific Fields
To get the users array:
jq '.users' data.json
To get the names of all users:
jq '.users[].name' data.json
Output:
"Alice" "Bob" "Charlie"
[]iterates over the array elements.
3. Filtering JSON Data
jq allows conditional selection using select(). For example, find all users with role "user":
jq '.users[] | select(.role=="user")' data.json
Output:
{
"id": 2,
"name": "Bob",
"role": "user"
}
{
"id": 3,
"name": "Charlie",
"role": "user"
}
If you want just their names:
jq -r '.users[] | select(.role=="user") | .name' data.json
Output:
Bob Charlie
-routputs raw strings without quotes.
4. Combining Filters and Transformation
You can transform JSON data, e.g., create a list of user IDs and names:
jq '.users[] | {id, name}' data.json
Output:
{
"id": 1,
"name": "Alice"
}
{
"id": 2,
"name": "Bob"
}
{
"id": 3,
"name": "Charlie"
}
5. Using jq with Command Output
Often, JSON comes from a command, not a file. For example, with curl:
curl -s https://jsonplaceholder.typicode.com/users | jq '.[].name'
Output:
"Leanne Graham" "Ervin Howell" ...
-ssilences curl progress output, and.[].nameiterates over array items and extracts thename.
6. Nested JSON Fields
For deeper structures, use dot notation:
{
"project": {
"name": "MyApp",
"repo": { "url": "https://github.com/example/myapp", "stars": 42 }
}
}
Access the repository URL:
jq '.project.repo.url' project.json
7. Counting Items in an Array
Get the number of users:
jq '.users | length' data.json
8. Advanced: Mapping Arrays
Suppose you want a simple CSV of user IDs and names:
jq -r '.users[] | "\(.id),\(.name)"' data.json
Output:
1,Alice 2,Bob 3,Charlie
Practical Examples
- Filter AWS CLI output:
aws ec2 describe-instances | jq '.Reservations[].Instances[] | {InstanceId, State: .State.Name}'
- Filter Kubernetes pods:
kubectl get pods -o json | jq '.items[] | {name: .metadata.name, status: .status.phase}'
- Extract URLs from JSON APIs:
curl -s https://api.example.com/resources | jq -r '.[].url'
Tips & Tricks
jq '.'→ Pretty-print JSON.jq -r→ Get raw strings (no quotes).- Pipe multiple
jqfilters:jq '.a | .b | .c'. - Use
select()for conditional filtering. - Combine filters and string interpolation for flexible outputs.
Conclusion
jq is a simple but incredibly powerful tool for anyone dealing with JSON on the command line. Once you get comfortable with its syntax, you can filter, format, and transform JSON data in ways that make automation and scripting much easier.