- 🧰 Bash doesn't natively support JSON—it's best parsed using dedicated tools like jq.
- 💡
jq -csimplifies JSON array iteration by outputting each object as one line. - 🔐 Using
readwith jq ensures safer variable assignment in Bash scripts. - ⚠️ The
?operator and//fallback in jq prevent crashes due to missing fields. - 🚀 JSON parsing in Bash is important for today's DevOps work and API connections.
Automating tasks through Bash scripting is powerful. But working with JSON data in shell scripts can be hard without the right tools. Whether you're getting API responses, parsing config files, or managing deployment settings, looping through JSON and getting values with tools like jq saves time and makes fewer mistakes. This guide shows you how to parse and change JSON data in Bash scripts using jq.
Bash Has No Native JSON Parser
The Bash shell wasn't made for parsing structured data formats like JSON. It can handle simple text changes using tools such as grep, awk, and sed. But these don't work well for JSON's nested setup and complex data. Even a small formatting difference—like spaces or special characters—can cause traditional Unix text tools to act strangely.
For example, look at this JSON:
{
"name": "Jane",
"details": {
"email": "jane@example.com",
"roles": ["admin", "editor"]
}
}
Getting values with sed or grep quickly becomes unreliable when the structure grows or changes. Because of this, you need a JSON-aware tool like jq.
Why Use jq for JSON in Bash?
jq is a command-line JSON processor made to filter, get, and change JSON data. Think of it as sed for JSON—but much stronger. It understands the JSON structure. This means it can reliably get to nested keys, arrays, and even use 'if-then' logic on data.
Advantages of jq
- Lightweight and fast
- Works on Linux, macOS, and Windows
- Lets you build strong queries
- Handles nested JSON and arrays easily
- Puts out safe, predictable formatting (good for scripts)
Installing jq
To start using jq, install it with your system’s package manager:
# Debian/Ubuntu
sudo apt install jq
# macOS with Homebrew
brew install jq
# RedHat/CentOS
sudo yum install jq
# Windows (with Chocolatey)
choco install jq
Once installed, run jq --version to confirm it's working.
Basic jq Examples
Here are some basic ways to get comfortable with jq:
Get a single field
jq '.name' config.json
Get raw string (no quotes or escape characters)
jq -r '.name' config.json
Get nested field
jq -r '.details.email' config.json
Get array values
jq -r '.details.roles[]' config.json
Print JSON neatly
jq '.' config.json
Reading JSON in Bash
Before parsing JSON, you usually read it into your script:
json=$(<config.json)
Good ways to do it:
- Use
$(<filename)instead ofcat filename |to not use extra background processes. - Quote the variable when passing to
jq, e.g.,echo "$json" | jqto stop words from splitting.
Avoid:
cat config.json | jq '.name' # Less efficient
Instead, use:
jq '.name' config.json # More efficient
Using jq to Loop Through JSON Arrays in Bash
Looping through arrays is common. JSON lists often show groups like users, settings, or records.
Example JSON Array
{
"users": [
{ "name": "Alice", "email": "alice@example.com" },
{ "name": "Bob", "email": "bob@example.com" }
]
}
Bash and jq Loop Pattern
for row in $(jq -c '.users[]' config.json); do
name=$(echo "$row" | jq -r '.name')
email=$(echo "$row" | jq -r '.email')
echo "User $name with contact $email"
done
Key Notes:
-csends out "compact" JSON: one object per line. Perfect for Bash loops.- Always quote
$rowwhen piping. It stops problems from special characters or line breaks.
This approach works well for short, well-structured JSON arrays. For larger or multiline data, while read loops or mapfile can work better.
Getting JSON Values into Variables
A strong way is using jq to define variables right within Bash:
name=$(jq -r '.user.name' config.json)
This quickly loads values for logic, logging, or passing into other tools.
Safer with read
To stop problems from new lines or encoding issues, use read:
read name <<< "$(jq -r '.user.name' config.json)"
You can even assign multiple values:
read name email <<< "$(jq -r '.user.name + " " + .user.email' config.json)"
Or use an array:
readarray -t roles < <(jq -r '.user.roles[]' config.json)
Now ${roles[0]}, etc., have each role in a clear way.
Parsing Nested JSON Structures in Bash
JSON isn’t flat—it often has many levels and arrays. Thankfully, jq gets to nested parts in a clear way.
Example Nested JSON
{
"service": {
"metadata": {
"id": "svc123",
"config": {
"enabled": true,
"thresholds": [10, 20, 30]
}
}
}
}
Query Nested Value
jq -r '.service.metadata.config.enabled' config.json
Loop Over Nested Array
jq -r '.service.metadata.config.thresholds[]' config.json
Use jq -c if each array element is an object:
jq -c '.services[].config' config.json
You can chain these together to go many levels deep. This lets you combine filters, conditions, and array indexing.
Handle Errors and Missing Fields Gracefully
Missing or unexpected keys can break your script. jq has safe ways to find things:
Optional Field with ?
jq -r '.user?.email' config.json
This stops errors if the user object is not there.
Default/Fallback Values with //
jq -r '.user.name // "Unknown"' config.json
This gives a fallback if the name is null or missing.
Conditional with if Expression
jq -r 'if has("user") then .user.name else "N/A" end' config.json
You can put this logic into your scripts to replace missing info or react the right way.
Popular JSON Bash Use Cases
Here’s where bash json loop, extract json values bash, and jq bash script ways are most helpful:
-
CI/CD Pipelines
Parse setup details from JSON for Docker, Kubernetes, or Terraform. -
API Connections
Read outputs from REST APIs and start actions (e.g., send Slack alerts, record deployment states). -
Setup Management
Load script options from JSON to control how it acts on the fly. -
Monitoring Scripts
Parse data about system health from JSON to manage warning paths.
Avoid Bash Pitfalls with JSON Data
Don’t:
- 🚫 Use
evalto process JSON (security risk) - 🚫 Loop using
for x in $(cat file)when data can contain line breaks - 🚫 Assume fields or array sizes—always check and test
Do:
- ✅ Use
jq -rto get raw strings - ✅ Quote variables passed to commands:
echo "$json" - ✅ Test fallback paths for missing keys
These steps will make your scripts stronger and easier to keep up.
Real-Life Example: Parse API Response in Bash
Let’s work with live data from an external API (fake endpoint used here):
response=$(curl -s https://api.example.com/data)
Get Values in a Loop
for row in $(echo "$response" | jq -c '.results[]'); do
id=$(echo "$row" | jq -r '.id')
status=$(echo "$row" | jq -r '.status')
echo "Item $id has status $status"
done
This works well when you watch logs, work with data from others, or react to live events using webhooks.
Reusable Bash Functions for JSON Parsing
Change your code to use helper functions:
extract_value() {
local path=$1
local file=$2
jq -r "$path" "$file"
}
user_id=$(extract_value '.user.id' config.json)
For more complex logic:
extract_nested_array() {
jq -r "$1[]" "$2"
}
extract_nested_array '.service.metadata.config.thresholds' config.json
Functions mean less copying and pasting. They also make fixing problems easier.
Speed Up with jq Shortcuts and Aliases
Make your work better with these Bash aliases:
alias jqp="jq '.' | less"
alias jql="jq -r"
Create Inline CLI Tools
#!/bin/bash
# jsongrep.sh
jq -r ".$1" "$2"
Invoke as:
./jsongrep.sh user.name config.json
When you mix Bash's simplicity with jq's flexibility, you get strong development tools fast.
When to Move Beyond Bash for JSON
Bash has limits—especially with very nested, big, or changing data setups. Then, you should switch to:
- Python: Has full parsing with its
jsonmodule—great for strong tools. - Node.js: Parses data based on events with easy rules.
- Go/Rust: Fast tools for handling JSON in live systems.
But for small to medium automation, jq and Bash scripts work very well.
Final Takeaways
Learning how to use bash json loop and get values with jq opens up many ways to automate tasks. This goes from local scripts to live system setups. Whether you're working with API outputs, setup lists, or nested objects, jq helps Bash work smoothly with JSON.
- Stick to jq for safe, reliable parsing
- Use read and
jq -rto manage values in variables - Loop through arrays in a clear way using
-cand quoted inputs - Check input JSON before you work with it
- Think about changing languages if things get too hard
With these skills, you can make scripting easier across CI pipelines, APIs, DevOps tools, and more—you won't need other programming languages.
Citations
Travers, N. (2022). Why jq is the universal JSON CLI tool for developers. Linux Journal. Retrieved from https://linuxjournal.com
Stack Overflow Developer Survey. (2023). Most commonly used tools among developers. StackOverflow Insights. Retrieved from https://insights.stackoverflow.com