json 将一系列散列压缩成单个散列

eqqqjvef  于 2023-11-20  发布在  其他
关注(0)|答案(3)|浏览(105)

我正在处理foo.json中的一个大型json结构
在完成这个过滤器jq '.[] | select(.entity_id|test("sensor.current.")) | { (.entity_id) : .state} ' foo.json后,用select()减少了组件列表,我得到:

{
  "sensor.current_consumption": "1.4"
}
{
  "sensor.current_power": "194.6"
}
{
  "sensor.current_mains_voltage": "239.9"
}

字符串
我想要的是{ "sensor.current_consumption": "1.4", "sensor.current_power": "194.6", "sensor.current_mains_voltage": "239.9" }
我试着读了jq的map()和add(),但没有多大意义。类似的问题以前也被问过,我试着看答案,例如here

jq '.[] | select(.entity_id|test("sensor.current.")) | map({ (.entity_id) : .state}) | add   ' foo.json
jq: error (at foo.json:0): Cannot index string with string "entity_id"


jq '.[] | select(.entity_id|test("sensor.current.")) | map({ (.entity_id) : .state}) | add   ' foo.json
rrent.")) | map({ (.entity_id) : .state}) | add   ' foo.foo


欢迎任何帮助

d8tt03nd

d8tt03nd1#

如果你的输入很大,你可能想使用reduce来迭代地构建你的输出对象:

… | reduce (.[] | select(.entity_id | test("sensor.current."))) as $item ({};
      .[$item.entity_id] = $item.state
    )

字符串
请注意,test使用正则表达式,因此"sensor.current."中的.表示任何字符。您可能需要使用containsstartswith

p5fdfcr1

p5fdfcr12#

不要用.[]将数组中的元素重命名,而是将它们map到一个新数组中,然后将它们add到一个对象中:

map(select(.entity_id|startswith("sensor.current.")) | { (.entity_id) : .state})
| add

字符串
或者,reduce到最终对象:

reduce (.[] | select(.entity_id|startswith("sensor.current.")))
as $x ({}; .[$x.entity_id] = $x.state)


第三个选项是使用from_entries从key-value-pairs数组构造一个对象:

map(select(.entity_id|startswith("sensor.current.")) | { key: .entity_id, value: .state})
| from_entries

zbsbpyhn

zbsbpyhn3#

这对我来说很有效,

jq 'map(select(.entity_id|startswith("sensor.current")) | { (.entity_id) : .state})| add' foo.json

字符串
非常感谢@ martl和@pmf

相关问题