jq refresher



jq Tutorial with Examples & Output

Let me walk through this with real JSON data and actual outputs.

Sample Data

{
  "users": [
    {"id": 1, "name": "Alice", "age": 28, "dept": "engineering", "salary": 95000},
    {"id": 2, "name": "Bob", "age": 35, "dept": "sales", "salary": 75000},
    {"id": 3, "name": "Charlie", "age": 24, "dept": "engineering", "salary": 65000},
    {"id": 4, "name": "Diana", "age": 42, "dept": "management", "salary": 120000},
    {"id": 5, "name": "Eve", "age": 31, "dept": "sales", "salary": 80000}
  ]
}

Basic Navigation

Get the users array:

$ jq '.users' data.json

Output:

[
  {"id": 1, "name": "Alice", "age": 28, ...},
  {"id": 2, "name": "Bob", "age": 35, ...},
  ...
]

Get first user:

$ jq '.users[0]' data.json

Output:

{
  "id": 1,
  "name": "Alice",
  "age": 28,
  "dept": "engineering",
  "salary": 95000
}

Get all names:

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

Output:

"Alice"
"Bob"
"Charlie"
"Diana"
"Eve"

Filtering with select (Core Topic)

Simple Comparison

Get users older than 30:

$ jq '.users[] | select(.age > 30)' data.json

Output:

{
  "id": 2,
  "name": "Bob",
  "age": 35,
  "dept": "sales",
  "salary": 75000
}
{
  "id": 4,
  "name": "Diana",
  "age": 42,
  "dept": "management",
  "salary": 120000
}
{
  "id": 5,
  "name": "Eve",
  "age": 31,
  "dept": "sales",
  "salary": 80000
}

Equality Match

Get the user named Alice:

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

Output:

{
  "id": 1,
  "name": "Alice",
  "age": 28,
  "dept": "engineering",
  "salary": 95000
}

Multiple Conditions (AND)

Get engineering employees earning more than 70k:

$ jq '.users[] | select(.dept == "engineering" and .salary > 70000)' data.json

Output:

{
  "id": 1,
  "name": "Alice",
  "age": 28,
  "dept": "engineering",
  "salary": 95000
}

Multiple Conditions (OR)

Get users from sales OR management:

$ jq '.users[] | select(.dept == "sales" or .dept == "management")' data.json

Output:

{
  "id": 2,
  "name": "Bob",
  "age": 35,
  "dept": "sales",
  "salary": 75000
}
{
  "id": 4,
  "name": "Diana",
  "age": 42,
  "dept": "management",
  "salary": 120000
}
{
  "id": 5,
  "name": "Eve",
  "age": 31,
  "dept": "sales",
  "salary": 80000
}

String Contains

Get users whose name contains 'a' (case-insensitive):

$ jq '.users[] | select(.name | test("a"; "i"))' data.json

Output:

{
  "id": 1,
  "name": "Alice",
  "age": 28,
  "dept": "engineering",
  "salary": 95000
}
{
  "id": 3,
  "name": "Charlie",
  "age": 24,
  "dept": "engineering",
  "salary": 65000
}
{
  "id": 4,
  "name": "Diana",
  "age": 42,
  "dept": "management",
  "salary": 120000
}

Range Check

Get users aged 25-35:

$ jq '.users[] | select(.age >= 25 and .age <= 35)' data.json

Output:

{
  "id": 1,
  "name": "Alice",
  "age": 28,
  "dept": "engineering",
  "salary": 95000
}
{
  "id": 2,
  "name": "Bob",
  "age": 35,
  "dept": "sales",
  "salary": 75000
}
{
  "id": 5,
  "name": "Eve",
  "age": 31,
  "dept": "sales",
  "salary": 80000
}

Combining Filter + Transform

Get names of all engineering employees:

$ jq '.users[] | select(.dept == "engineering") | .name' data.json

Output:

"Alice"
"Charlie"

Get a subset of fields for high earners:

$ jq '.users[] | select(.salary > 80000) | {name, salary}' data.json

Output:

{
  "name": "Alice",
  "salary": 95000
}
{
  "name": "Diana",
  "salary": 120000
}
{
  "name": "Eve",
  "salary": 80000
}

Building Arrays with Filters

Get an array of all high earners (not separate objects):

$ jq '[.users[] | select(.salary > 80000)]' data.json

Output:

[
  {
    "id": 1,
    "name": "Alice",
    "age": 28,
    "dept": "engineering",
    "salary": 95000
  },
  {
    "id": 4,
    "name": "Diana",
    "age": 42,
    "dept": "management",
    "salary": 120000
  },
  {
    "id": 5,
    "name": "Eve",
    "age": 31,
    "dept": "sales",
    "salary": 80000
  }
]

Count how many are in engineering:

$ jq '[.users[] | select(.dept == "engineering")] | length' data.json

Output:

2

Common Gotchas

❌ This won't work as expected (returns null, not filtered array):

$ jq '.users | select(.dept == "sales")'
# Tries to filter the whole array, not individual items

✅ Correct way (iterate first, then filter):

$ jq '.users[] | select(.dept == "sales")'
# Iterate with [], then apply select

Need help with a specific filtering scenario? Just show me your data structure and what you're trying to filter!




Comments

Popular posts from this blog

Windows SSH: Permissions for 'private-key' are too open

NodeJS: Error: spawn EINVAL in window for node version 20.20 and 18.20