Skip to content
jq Command in Linux — JSON Processor with Examples

jq Command in Linux — JSON Processor with Examples

DodaTech Updated Jun 20, 2026 7 min read

jq is a lightweight command-line JSON processor for Linux. It lets you slice, filter, map, and transform structured JSON data with a simple expression language — essential for working with modern APIs and configuration files.

What You’ll Learn

By the end of this tutorial, you’ll know how to access object keys, navigate arrays, select values by condition, pipe filters, map over arrays, get length, combine multiple filters, output raw strings, and pretty-print JSON.

Why jq Matters

JSON is everywhere — REST APIs, cloud configuration, Docker metadata, Kubernetes resources, and CI/CD pipelines. jq is the fastest way to extract, transform, and explore JSON from the command line. Durga Antivirus Pro uses jq to parse threat intelligence JSON feeds, and DodaZIP uses it to process API responses from cloud storage services.

jq Learning Path

    flowchart LR
  A[curl Command] --> B[jq Command<br/>You are here]
  B --> C[API Testing & Automation]
  B --> D[Shell Scripting]
  style B fill:#f90,color:#fff
  
Prerequisites: Bash terminal. The curl tutorial helps since they’re often used together.

Syntax Overview

jq [options] 'filter' [file...]
OptionDescription
-rRaw output (no quotes around strings)
-cCompact output (each JSON object on one line)
-f fileRead filter from file
--arg k vPass shell variable as jq variable

10 Practical Examples

Create a sample JSON file:

cat > data.json << 'EOF'
{
  "users": [
    {
      "id": 1,
      "name": "Alice Johnson",
      "email": "alice@example.com",
      "role": "admin",
      "active": true,
      "salary": 75000,
      "skills": ["Linux", "Python", "Docker"]
    },
    {
      "id": 2,
      "name": "Bob Smith",
      "email": "bob@example.com",
      "role": "user",
      "active": false,
      "salary": 62000,
      "skills": ["JavaScript", "React"]
    },
    {
      "id": 3,
      "name": "Charlie Brown",
      "email": "charlie@example.com",
      "role": "user",
      "active": true,
      "salary": 88000,
      "skills": ["Go", "Kubernetes", "AWS"]
    }
  ],
  "total": 3,
  "source": "employees_db"
}
EOF

1. Access Object Keys

Get the total count:

jq '.total' data.json
3

Get the source field:

jq '.source' data.json
"employees_db"

2. Array Access

Get the first user:

jq '.users[0]' data.json
{
  "id": 1,
  "name": "Alice Johnson",
  "email": "alice@example.com",
  "role": "admin",
  "active": true,
  "salary": 75000,
  "skills": ["Linux", "Python", "Docker"]
}

Get all user names:

jq '.users[].name' data.json
"Alice Johnson"
"Bob Smith"
"Charlie Brown"

Get the last user’s skills:

jq '.users[-1].skills' data.json
["Go", "Kubernetes", "AWS"]

3. Select Values by Condition

Find active users:

jq '.users[] | select(.active == true)' data.json
{
  "id": 1,
  "name": "Alice Johnson",
  "active": true,
  "salary": 75000
}
{
  "id": 3,
  "name": "Charlie Brown",
  "active": true,
  "salary": 88000
}

Find users with salary > 70000:

jq '.users[] | select(.salary > 70000) | {name, salary}' data.json
{
  "name": "Alice Johnson",
  "salary": 75000
}
{
  "name": "Charlie Brown",
  "salary": 88000
}

4. Pipe (|) Filters

Get names of admins:

jq '.users[] | select(.role == "admin") | .name' data.json
"Alice Johnson"

Get name and email of inactive users:

jq '.users[] | select(.active == false) | {name, email}' data.json
{
  "name": "Bob Smith",
  "email": "bob@example.com"
}

5. Map Over Arrays

Transform all names to uppercase:

jq '[.users[] | {name: (.name | ascii_upcase), role}]' data.json
[
  {
    "name": "ALICE JOHNSON",
    "role": "admin"
  },
  {
    "name": "BOB SMITH",
    "role": "user"
  },
  {
    "name": "CHARLIE BROWN",
    "role": "user"
  }
]

Add a computed field:

jq '[.users[] | {name, annual_salary: (.salary * 12)}]' data.json
[
  {
    "name": "Alice Johnson",
    "annual_salary": 900000
  },
  {
    "name": "Bob Smith",
    "annual_salary": 744000
  },
  {
    "name": "Charlie Brown",
    "annual_salary": 1056000
  }
]

6. Length

Count users:

jq '.users | length' data.json
3

Count skills per user:

jq '.users[] | {name, skill_count: (.skills | length)}' data.json
{
  "name": "Alice Johnson",
  "skill_count": 3
}
{
  "name": "Bob Smith",
  "skill_count": 2
}
{
  "name": "Charlie Brown",
  "skill_count": 3
}

7. Multiple Filters

Get multiple fields:

jq '.users[] | .name, .email, .role' data.json
"Alice Johnson"
"alice@example.com"
"admin"
"Bob Smith"
"bob@example.com"
"user"
"Charlie Brown"
"charlie@example.com"
"user"

8. Raw Output (-r)

Without -r, strings are quoted:

jq '.users[0].email' data.json
"alice@example.com"

With -r, quotes are stripped:

jq -r '.users[0].email' data.json
alice@example.com

Useful for piping into other commands:

jq -r '.users[] | select(.role == "admin") | .email' data.json | while read email; do
    echo "Emailing $email"
done
Emailing alice@example.com

9. Filter by Condition with Multiple Criteria

Find users with salary > 60000 AND skill count >= 3:

jq '.users[] | select(.salary > 60000 and (.skills | length) >= 3)' data.json
{
  "id": 1,
  "name": "Alice Johnson",
  "salary": 75000,
  "skills": ["Linux", "Python", "Docker"]
}
{
  "id": 3,
  "name": "Charlie Brown",
  "salary": 88000,
  "skills": ["Go", "Kubernetes", "AWS"]
}

10. Pretty Print and Compact

Pretty print (default):

echo '{"name":"Alice","city":"NYC"}' | jq '.'
{
  "name": "Alice",
  "city": "NYC"
}

Compact output:

echo '{"name":"Alice","city":"NYC"}' | jq -c '.'
{"name":"Alice","city":"NYC"}

Common Use Cases

Pipe curl Output to jq

curl -s https://api.github.com/repos/curl/curl | jq '{stars: .stargazers_count, forks: .forks_count}'

Extract Values from Nested JSON

jq -r '.users[] | "\(.name): \(.email)"' data.json
Alice Johnson: alice@example.com
Bob Smith: bob@example.com
Charlie Brown: charlie@example.com

Compute Averages

jq '[.users[].salary] | add / length' data.json
75000

Filter Array with Multiple Conditions

jq '[.users[] | select(.active and .salary > 70000)] | length' data.json
2

Common Mistakes

1. Forgetting the Filter

jq without a filter prints nothing. Always provide at least . to output the whole input.

2. Confusing Array and Object Access

Use .[] to iterate array elements. Use .key to access object keys. .[0] gets the first array element.

3. Not Using Raw Output for Text Processing

When piping jq to other commands, always use -r. Without it, strings remain quoted, which breaks downstream tools.

4. Missing Parentheses for Complex Expressions

select(.active and .salary > 70000) — the select function takes a single expression. Use parentheses for grouping with or/and.

Practice Questions

1. How do you get all values of a specific key across an array?

jq '.users[].name' data.json

2. What does jq -r '.users[0].email' output?

alice@example.com — no quotes around the string.

3. How do you count objects in an array?

jq '.users | length' data.json

4. How do you filter array elements by a condition?

jq '.users[] | select(.active == true)' data.json

5. Challenge: Write a jq filter that returns the average salary of active users only.

jq '[.users[] | select(.active) | .salary] | add / length' data.json

Mini Project: API Response Analyzer

#!/bin/bash
# api_analyze.sh — Analyze a JSON API response
# Usage: ./api_analyze.sh response.json

FILE="${1:-data.json}"

if [ ! -f "$FILE" ]; then
    echo "Error: File not found: $FILE"
    exit 1
fi

echo "=== JSON Analysis Report ==="
echo "File: $FILE"
echo ""

echo "Top-level keys:"
jq -r 'keys | .[]' "$FILE" | tr '\n' ' '
echo -e "\n"

echo "User summary:"
jq -r '["Name", "Role", "Active", "Salary"], 
        (.users[] | [.name, .role, .active, .salary]) | 
        @tsv' "$FILE" | column -t -s $'\t'

echo ""
echo "Stats:"
echo "  Total users: $(jq '.users | length' "$FILE")"
echo "  Active users: $(jq '[.users[] | select(.active)] | length' "$FILE")"
echo "  Average salary: $(jq '[.users[].salary] | add / length' "$FILE")"

Expected output:

=== JSON Analysis Report ===
File: data.json

Top-level keys:
source total users

User summary:
Name            Role    Active  Salary
Alice Johnson   admin   true    75000
Bob Smith       user    false   62000
Charlie Brown   user    true    88000

Stats:
  Total users: 3
  Active users: 2
  Average salary: 75000

FAQ

How do I install jq?
jq is available in all major package managers: sudo apt install jq (Debian/Ubuntu), sudo dnf install jq (Fedora), brew install jq (macOS).
Can jq modify JSON files?
jq is a filter — it reads input and writes output. Use shell redirection to save: jq '.key = "value"' file.json > new.json && mv new.json file.json.
What’s the difference between .users[] and .users?
.users returns the array as-is. .users[] iterates over each element, producing multiple outputs (one per element).
Can jq handle streaming JSON?
Yes, with --stream. This is useful for very large JSON files that don’t fit in memory.

What’s Next

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro