使用jq创建JSON

3

我正在尝试使用jq从命令"lsb_release"的结果创建JSON文件。

我已经完成了以下工作:

if [ -x "$(command -v lsb_release)" ]; then
    lsb_release -a  | jq  --raw-input 'split("\t") | { (.[0]) : .[1] }' > ubuntu_release.json
fi

结果是

{
  "Distributor ID:": "Ubuntu"
}

{
  "Description:": "Ubuntu 20.04.3 LTS"
}

{
  "Release:": "20.04"
}

{
  "Codename:": "focal"
}

但我想要结果

[
    {
      "Distributor ID:": "Ubuntu"
    },
    {
      "Description:": "Ubuntu 20.04.3 LTS"
    },
    {
      "Release:": "20.04"
    },
    {
      "Codename:": "focal"
    }
]

能有人帮帮我吗?:)
2个回答

8
通常,当我们想要从输入流创建数组时,可以使用--slurp/-s。但是,当与--raw-input/-R结合使用时,这会导致整个输入作为单个字符串(包含换行符)提供。
也可以使用--null-input/-n[ inputs | ... ]来实现 slurping。对于文本文件,此方法也可以正常工作。
jq -nR '[ inputs | split("\t") | { (.[0]) : .[1] } ]'

此处有 jqplay 的示例程序。


话虽如此,我认为您会发现以下输出格式更有用:

{
  "Distributor ID": "Ubuntu",
  "Description": "Ubuntu 20.04.3 LTS",
  "Release": "20.04",
  "Codename": "focal"
}

这可以通过简单地添加| add来实现。
jq -nR '[ inputs | split(":\t") | { (.[0]) : .[1] } ] | add'

jqplay 上的演示

也可以使用 reduce

jq -nR 'reduce ( inputs | split(":\t") ) as [ $k, $v ] ( {}; . + { ($k): $v } )'

在 jqplay 上的演示


非常感谢。 - Valentin Leblanc
已添加到答案。 - ikegami
1
实际上,拥有一个 JSON 对象比数组要好得多 :) 再次感谢! - Valentin Leblanc

0

过滤器

reduce (inputs / ":\t") as [$key, $value] ({}; .+{($key): $value})

输入

Distributor ID: Ubuntu
Description:    Ubuntu 20.04.3 LTS
Release:    20.04
Codename:   focal

输出

{
  "Distributor ID": "Ubuntu",
  "Description": "Ubuntu 20.04.3 LTS",
  "Release": "20.04",
  "Codename": "focal"
}

请注意,从 `inputs` 中获取的 `$key` 和 `$value` 的每行都会被reduce处理并组合

演示

https://jqplay.org/s/ZBvKf6vQ0F


这与3个月前发布的解决方案完全相同。你只是将| split(":\t")改成了/ ":\t"。你甚至没有解释为什么提供了与原帖要求不同的输出结果。 - ikegami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接