Skip to content
Go back

jq One-Liners Every Sysadmin Needs

By SumGuy 4 min read
jq One-Liners Every Sysadmin Needs

Why jq Matters

Every API, every log aggregator, every cloud tool outputs JSON. Parsing it with grep and cut is 2008 thinking. jq is sed for JSON—and it’s damn useful.

The catch: jq has a learning curve. But these 5 one-liners handle 80% of real work.

1. Extract a Nested Field

You have a JSON response. You need one field three levels deep. Classic API torture.

Terminal window
curl https://api.example.com/user/123 | jq '.data.user.email'

That’s it. .data.user.email is a path. If the user doesn’t exist, you get null. No errors, no fuss.

More complex: get all emails from an array of users:

Terminal window
echo '[{"name":"alice","email":"alice@example.com"},{"name":"bob","email":"bob@example.com"}]' | jq '.[] | .email'

.[] iterates. Pipe to .email and you get:

"alice@example.com"
"bob@example.com"

2. Filter by Condition

You have logs. You want only ERROR entries.

Terminal window
cat logs.json | jq '.[] | select(.level == "ERROR")'

select() filters. Only entries where .level equals “ERROR” pass through.

Need multiple conditions?

Terminal window
cat logs.json | jq '.[] | select(.level == "ERROR" and .service == "api")'

Now you get errors from the api service only.

Want the opposite? Exclude a condition:

Terminal window
cat logs.json | jq '.[] | select(.level != "DEBUG")'

3. Restructure (Map)

API returns user data. You only want name and email, and you want to rename fields:

Terminal window
curl https://api.example.com/users | jq '.[] | {username: .name, contact: .email}'

Output:

{
"username": "alice",
"contact": "alice@example.com"
}
{
"username": "bob",
"contact": "bob@example.com"
}

{field: .path} syntax creates a new object with whatever fields you want.

4. Combine Multiple Results

You’re calling an API multiple times. Each returns an array. You want them all in one.

Terminal window
(curl api/users; curl api/admins) | jq -s 'add'

-s means “slurp”—collect everything into one array. add concatenates arrays.

Output: one big array with all users and admins.

Need a more sophisticated merge?

Terminal window
curl api/user/1 | jq '. + {retrieved_at: now}'

. + {key: value} adds a field. now is the current Unix timestamp.

5. Pretty-Print and Compact

Raw JSON is a wall of text. Pretty-print it (default behavior):

Terminal window
curl https://api.example.com/data | jq .

Need it compact for storage or piping?

Terminal window
curl https://api.example.com/data | jq -c .

-c is compact. One object per line, no whitespace.

Bonus: Conditional Logic

You have a config file. If a field exists, use it; otherwise, use a default:

Terminal window
cat config.json | jq '.timeout // 30'

// 30 means: if .timeout is null or missing, use 30. Called the “alternative operator.”

Build a string with conditions:

Terminal window
cat users.json | jq '.[] | "\(.name) <\(.email)>"'

Output:

alice <alice@example.com>
bob <bob@example.com>

String interpolation with \(...) inside double quotes.

The Power Move

Combine everything:

Terminal window
curl https://api.example.com/logs | jq -c '.[] | select(.level == "ERROR") | {time: .timestamp, msg: .message, service: .service} | "\(.time): [\(.service)] \(.msg)"'

That pipes stdout to a formatted error report. One line. No Python needed.

6. Flatten Nested Arrays

You’ve got deeply nested JSON and want all values flattened to a single array:

Terminal window
echo '[[1,2],[3,[4,5]]]' | jq 'flatten'
# [1, 2, 3, 4, 5]
echo '[[1,2],[3,[4,5]]]' | jq 'flatten(1)'
# [1, 2, 3, [4, 5]] -- only one level deep

Useful when an API returns paginated results in arrays of arrays.

7. CSV Output

Export JSON as CSV for spreadsheets or awk:

Terminal window
curl https://api.example.com/users | jq -r '.[] | [.name, .email, .role] | @csv'

Output:

"alice","alice@example.com","admin"
"bob","bob@example.com","user"

-r removes the outer quotes. @csv handles escaping automatically. Pipe it to a file and open in Excel.

8. Object to Key-Value Pairs

Turn an object into an array of {key, value} pairs — useful for iterating over unknown keys:

Terminal window
echo '{"host":"db.internal","port":5432,"ssl":true}' | jq 'to_entries[]'

Output:

{"key": "host", "value": "db.internal"}
{"key": "port", "value": 5432}
{"key": "ssl", "value": true}

Reverse it with from_entries. Handy when you’re building configs dynamically.

Getting Unstuck

jq is expressive but cryptic. When stuck:

Ten minutes reading the jq manual answers 90% of use cases. After that, you’re faster with jq than any Python script — and you don’t need to install anything.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it may appear here.


Previous Post
Why Your TLS Certificate Isn't Trusted
Next Post
Certificate Expiry: Monitor Before the 3 AM Call

Related Posts