Sample output
web-02 10.0.1.11 62
api-01 10.0.2.10 78
db-01 10.0.3.10 91
Three of the five servers are above 60 percent CPU, and the output is plain tab-separated text with no JSON left in it. db-01 at 91 is the one to look at first; pipe through sort -t$'\t' -k3 -nr if the list gets longer.
When you would reach for it
An API response with a hundred objects when you care about four of them, a kubectl get -o json dump, a cloud inventory export, or a config file you need to query from a script. grep finds lines, but JSON objects span lines and their fields can appear in any order, so a text search either misses records or matches the wrong field. select asks the question against the parsed structure instead.
Gotchas
- Types matter, and a mismatch fails silently.
select(.cpu > "60")returns nothing and exits 0, because jq orders every number before every string, so no number is ever greater than"60". The same thing happens with--arg t 60, which passes the value in as a string. Use--argjsonfor numbers. - A missing field is
null, andnull > 60is false. A typo likeselect(.cpus > 60)drops every record without an error. If the output is unexpectedly empty, check the field name withjq '.servers[0] | keys' data.json. - An empty result exits 0 by default, so a script cannot tell “no matches” from “matched”. Add
-eand jq exits 4 when the program produces no output, or 1 when the last value isfalseornull. - Debian, Ubuntu, and Alpine base images do not include jq:
apt install jqorapk add jq. Debian 12 ships jq 1.6, which lacks newer builtins such aspick. The filter in this entry works on 1.6 and later.
Variants
$ jq '[.servers[] | select(.cpu > 60)] | length' data.json
Count the matches instead of listing them. The outer brackets collect every emitted value back into one array so length can measure it
$ t=60; jq -r --argjson t "$t" '.servers[] | select(.cpu > $t) | .name' data.json
Pass the threshold in from a shell variable. Never splice $t into the jq program with double quotes; --argjson keeps it a number and keeps the quoting sane
$ jq -r '.servers[] | select(.role == "frontend" and .cpu > 50) | .name' data.json
Combine conditions with and and or. String comparisons need the double quotes inside the single-quoted program