Cleaning, renaming and combining JSON objects is needed for config files, API payloads and reports.
Basic object functions:
keysreturns sorted key names (keys_unsortedkeeps input order),has("k")tests for a key,lengthcounts keys.del(.password, .internal)removes keys;pick(.a, .b.c)(1.7+) keeps only the given paths.to_entriesconverts{"a":1}into[{"key":"a","value":1}], andfrom_entriesconverts back.with_entries(f)isto_entries | map(f) | from_entries: the standard tool to rename, filter or transform keys.
Examples: with_entries(select(.value != null)) drops null fields; with_entries(.key |= ascii_upcase) uppercases keys; with_entries(select(.key | startswith("_") | not)) drops private keys.
Merging: + merges two objects, with the right side winning for duplicate keys, shallowly. * merges recursively, combining nested objects: perfect for applying an override on top of default config. add on an array of objects merges them all with +.
To combine two files, read both and merge: jq -s '.[0] * .[1]' defaults.json overrides.json.
Object key order is preserved in output, but most jq functions that list keys sort them; add -S to sort all output keys for stable diffs.
Example
echo '{"name":"api","port":8080,"_debug":true,"db":{"host":"x","pool":5},"tls":null}' > c.json
jq -c 'keys' c.json # ["_debug","db","name","port","tls"]
jq -c 'del(._debug, .tls)' c.json # {"name":"api","port":8080,"db":{"host":"x","pool":5}}
jq -c 'with_entries(select(.value != null))' c.json | jq -c 'has("tls")' # false
jq -c 'with_entries(select(.key | startswith("_") | not)) | keys' c.json
# ["db","name","port","tls"]
jq -c '{db: .db} + {db: {pool: 20}}' c.json # {"db":{"pool":20}}
jq -c '{db: .db} * {db: {pool: 20}}' c.json # {"db":{"host":"x","pool":20}}
jq -c 'to_entries[0]' c.json # {"key":"name","value":"api"}Remember
- keys, has, del, pick for inspecting and trimming
- with_entries(f) renames/filters keys via {key, value}
- + merges shallowly (right wins), * merges recursively
Watch out for
- Using + to apply nested config overrides and losing sibling keys; use * for deep merges.