Wilfred Hughes
Wilfred Hughes

Reputation: 31171

How do I remove all keys except one with jq?

Given a list of objects, with many keys I don't want:

[{
    "name": "Alice",
    "group": "Admins",
    "created": "2014"
}, {
    "name": "Bob",
    "group": "Users",
    "created": "2014"
}]

How do I filter these objects to only include keys I want?

[{
    "name": "Alice"
}, {
    "name": "Bob"
}]

I've tried jq '.[].name' but that extracts the values, rather than preserving the objects.

Upvotes: 32

Views: 22585

Answers (6)

Yan Foto
Yan Foto

Reputation: 11388

8 years later...

As of jq version 1.7, pick can be used:

jq 'pick(.[].name)'

Upvotes: 2

TJR
TJR

Reputation: 3773

This would allow keeping a set of fields (matched by regex).

map(
  to_entries
  |map(select(.key|test("^(name)$")))
  |from_entries
)

Upvotes: 0

peak
peak

Reputation: 116880

The accepted answer (with map) and the equivalent answer by @mauricio-tranjano will, in effect, add the specified key to objects that don't already have it. If that's not the behavior you want, then consider using has(_), e.g.:

$ jq -c 'map( if has("a") then {a} else {} end )'

Input:

[{id:1,a:1}, {id:2}]

Output:

[{"a":1},{}]

Upvotes: 6

Girish
Girish

Reputation: 12127

You can use the map() function to filter any key:

jq 'map({name: .name})'

Update

Suggested by @WilfredHughes: The above filter can be abbreviated as follows:

jq 'map({name})'

Upvotes: 36

Mauricio Trajano
Mauricio Trajano

Reputation: 2937

Another solution without the map function:

jq '[.[] | {name: .name}]'

Upvotes: 5

Hans Z.
Hans Z.

Reputation: 54028

you can use map with del if you know the keys you don't want:

jq 'map(del (.group) | del (.created))'

Upvotes: 25

Related Questions