使用JQ的值映射

时间:2015-08-07 21:59:36

标签: json jq

我有一个很大的JSON文件,我想根据某种映射转换一些值。

我看到的数据如下:

[
    {"id":1, "value":"yes"},
    {"id":2, "value":"no"},
    {"id":3, "value":"maybe"}
]

我想将其转换为这样的列表:

[
    {"id":1, "value":"10"},
    {"id":2, "value":"0"},
    {"id":3, "value":"5"}
]

使用固定映射:

yes => 10
no => 0
maybe => 5

我目前的解决方案基于一个简单的if-elif-else组合,如下所示:

cat data.json| jq '.data[] | .value = (if .value == "yes" then "10" elif .value == "maybe" then "5"  else "0" end)'

但这真的太丑了,我希望能有更直接的方式表达映射。

感谢您的帮助

3 个答案:

答案 0 :(得分:2)

如果想要避免在命令行上指定映射,则可能会关注以下两个变体。

第一个变体可以与jq 1.3,jq 1.4和jq 1.5:

一起使用
def mapping: {"yes":"10","no":"0","maybe":"5"};
map(.value |=  mapping[.])

下一个变体使用--argfile选项(自jq 1.4起可用),如果映射对象在文件中可用,则会很有用:

jq --argfile mapping mapping.jq 'map(.value |= $mapping[.])' data.json

最后,在jq 1.5中,基于 import 的其他替代方案也可用(!)。

答案 1 :(得分:1)

由于您正在翻译字符串值,因此您应该能够使用json对象来保存映射。然后映射将是微不足道的。

$ jq --arg mapping '{"yes":"10","no":"0","maybe":"5"}'
    'map(.value |= ($mapping | fromjson)[.])' data.json

答案 2 :(得分:0)

这是一个使用“内联”对象的解决方案,因为映射很小:

map(.value = {"yes":"10","no":"0","maybe":"5"}[.value])

可以使用|=缩短peak的解决方案:

map(.value |= {"yes":"10","no":"0","maybe":"5"}[.])