keeer
keeer

Reputation: 863

Using jq how can I replace the name of a key with something else

This should be easy enough... I want to rename a few keys (ideally with jq), whatever I do seems to error though. Here is a json example below:

[
 {
  "fruit": "strawberry",
  "veg": "apple",
  "worker": "gardener"
 }
]

I'd like to rename the veg key to fruit2 (or example, whatever is easiest) and also the worker key to job.

I realize this is possible in sed, but I'm trying to get to grips with jq

Upvotes: 52

Views: 34190

Answers (5)

mohRamadan
mohRamadan

Reputation: 639

jq '[.[] | { fruit2: .veg, other_key: .other_orig_key }]'

check this example

Upvotes: 1

wjordan
wjordan

Reputation: 20380

Here's how to use if-then-else-end with elif to rename multiple keys:

map(with_entries(.key |=
  if . == "fruit"  then "fruit2"
elif . == "worker" then "job"
else . end))

(jqplay example)

Note in the current development branch / upcoming 1.7 release the empty else branch will be optional and could be removed, but it's still required in v1.6.

Upvotes: 2

peak
peak

Reputation: 116670

The key (:-) is with_entries. E.g., given a single object:

with_entries(if .key == "veg" then .key = "fruit2" else . end)

In your case, since you have an array of objects, you could wrap the above in map( ... ).


Note that if the original JSON object already has a key named "fruit2", then the usual "last-most wins" rule applies, where in this case, "last-most" refers to the array of key-value pairs that is used to determine the final result (as per the def of with_entries).

Upvotes: 34

barakbd
barakbd

Reputation: 1102

For anyone looking to manipulate the key with a value from value:

$ echo '{ "foo": {"id": 123}, "bar": {"id":456} }'  | jq 'to_entries | map({key:(.key + "-" +(.value.id|tostring)), value:.value}) | from_entries'

If there is a shorter way to do it (maybe using with_entries), I would be happy to know.

Upvotes: 0

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Use the following jq approach:

jq '[.[] | .["fruit2"] = .veg | .["job"] = .worker | del(.veg, .worker)]' file

The output:

[
  {
    "fruit": "strawberry",
    "fruit2": "apple",
    "job": "gardener"
  }
]

Upvotes: 53

Related Questions