jq - 解析&基于json中键值对的替换

时间:2018-01-16 15:46:24

标签: json dictionary jq

我有一个键值映射形式的json文件。例如:

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

我有另一个json文件。必须根据第一个文件中的键替换第二个文件中的值。

例如,第二个文件是:

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

第二个文件应替换为

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

因为第一个文件中key1的值是user1。这可以用任何python程序完成,但我正在学习jq并想尝试使用jq本身。我尝试使用slurpfile读取文件的不同组合,然后选择&走路等但无法达到所需的解决方案。

对此相关的任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:1)

jq 解决方案:

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

输出:

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

答案 1 :(得分:1)

由于.users [0]是一个JSON字典,因此使用它是有意义的(例如效率):

调用:     jq -c --slurpfile用户users.json -f program.jq input.json

program.jq:

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

输出:

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

注意:上面假设字典不包含null或false值,或者应该忽略字典中的任何此类值。这避免了否则将需要的双重查找。如果此假设无效,则使用hasin(例如,由RomanPerekhrest提供)的解决方案将是合适的。

补充问题的解决方案

(参见“评论”。)

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

海绵

使用重定向覆盖输入文件是非常不可取的。 如果您有或可以安装sponge,那么使用它会好得多。有关详细信息,请参阅例如“什么是jq相当于sed -i?”在jq FAQ