简体   繁体   中英

jq - parsing& replacement based on key-value pairs within json

I have a json file in the form of a key-value map. For example:

{
    "users":[
    {
        "key1":"user1",
        "key2":"user2"
    }
  ]
}

I have another json file. The values in the second file has to be replaced based on the keys in first file.

For example 2nd file is:

{
    "info":
    {
    "users":["key1","key2","key3","key4"]
    }
}

This second file should be replaced with

{
    "info":
    {
    "users":["user1","user2","key3","key4"]
    }
}

Because the value of key1 in first file is user1. this could be done with any python program, but I am learning jq and would like to try if it is possible with jq itself. I tried different combinations with reading file using slurpfile, then select & walk etc. But couldn't arrive at the required solution.

Any suggestions for the same will be appreciated.

jq solution:

jq --slurpfile users 1st.json '$users[0].users[0] as $users 
     | .info.users |= map(if in($users) then $users[.] else . end)' 2nd.json

The output:

{
  "info": {
    "users": [
      "user1",
      "user2",
      "key3",
      "key4"
    ]
  }
}

Since .users[0] is a JSON dictionary, it would make sense to use it as such (eg for efficiency):

Invocation: jq -c --slurpfile users users.json -f program.jq input.json

program.jq:

$users[0].users[0] as $dict
| .info.users |= map($dict[.] // .)

Output:

{"info":{"users":["user1","user2","key3","key4"]}}

Note: the above assumes that the dictionary contains no null or false values, or rather that any such values in the dictionary should be ignored. This avoids the double lookup that would otherwise be required. If this assumption is invalid, then a solution using has or in (eg as provided by RomanPerekhrest) would be appropriate.

Solution to supplemental problem

(See "comments".)

$users[0].users[0] as $dict
| second
| .info.users |= (map($dict[.] | select(. != null)))

sponge

It is highly inadvisable to use redirection to overwrite an input file. If you have or can install sponge , then it would be far better to use it. For further details, see eg "What is jq's equivalent of sed -i?" in the jq FAQ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM