jq: generate JSON: 可以创建动态密钥吗?
jq: generate JSON: dynamic key creation possible?
我没用过jq生成JSON,只会解析。所以这对我来说是未涉足的领域。
我找到了 jq & bash: make JSON array from variable,这让我更接近我正在寻找的东西。但是,我还没有确定如何为我正在寻找的结构动态创建键名。
我正在寻找的结构看起来像这样:
{
"eth0":
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
},
"eth3":
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
}
源自 csv:
iface,key1,key2,key3
eth0,value1,value2,value3
eth3,value1,value2,value3
我一直遇到的问题是从 CSV 动态生成 JSON 中的密钥。我一直无法找到 jq 的能力。我正在使用 jq 1.5。
我是在旋转我的轮子吗?
编辑 - 可能的答案
目前正在调查这本食谱答案:
https://github.com/stedolan/jq/wiki/Cookbook#convert-a-csv-file-with-headers-to-json
理想情况下,您的输入应该是 JSON,因此您应该 运行 您的文件可以将您的 CSV 文件转换为包含您的数据的数组,以便 jq 可以使用它。假设您的数据不复杂并且值本身不包含逗号,您可以读入原始行并将它们拆分。那么这只是构建结果的问题。
$ jq -R 'split(",") as $k |
reduce (inputs | split(",")) as $r ({};
.[$r[0]] = ([range(1;$k|length) | { key: $k[.], value: $r[.] }] | from_entries)
)' input.csv
这是一个直接的解决方案,实际上与 Jeff 的解决方案非常相似(特别是,它对 CSV 做出了相同的假设),但第一行使用 input
,第二行使用 inputs
其余行,来自 jq Cookbook 的 "objectify" 的简化版本,以及 add
而不是主过滤器中的 reduce
:
jq -R -n '
def objectify(headers): . as $in
| reduce range(0; headers|length) as $i
({}; .[headers[$i]] = $in[$i] );
((input|split(","))[1:]) as $headers
| [ (inputs|split(",")) as $line
| { ($line[0]): ($line[1:] | objectify($headers)) } ]
| add
'
我没用过jq生成JSON,只会解析。所以这对我来说是未涉足的领域。
我找到了 jq & bash: make JSON array from variable,这让我更接近我正在寻找的东西。但是,我还没有确定如何为我正在寻找的结构动态创建键名。
我正在寻找的结构看起来像这样:
{
"eth0":
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
},
"eth3":
{
"key1": "value1",
"key2": "value2",
"key3": "value3"
}
}
源自 csv:
iface,key1,key2,key3
eth0,value1,value2,value3
eth3,value1,value2,value3
我一直遇到的问题是从 CSV 动态生成 JSON 中的密钥。我一直无法找到 jq 的能力。我正在使用 jq 1.5。
我是在旋转我的轮子吗?
编辑 - 可能的答案
目前正在调查这本食谱答案:
https://github.com/stedolan/jq/wiki/Cookbook#convert-a-csv-file-with-headers-to-json
理想情况下,您的输入应该是 JSON,因此您应该 运行 您的文件可以将您的 CSV 文件转换为包含您的数据的数组,以便 jq 可以使用它。假设您的数据不复杂并且值本身不包含逗号,您可以读入原始行并将它们拆分。那么这只是构建结果的问题。
$ jq -R 'split(",") as $k |
reduce (inputs | split(",")) as $r ({};
.[$r[0]] = ([range(1;$k|length) | { key: $k[.], value: $r[.] }] | from_entries)
)' input.csv
这是一个直接的解决方案,实际上与 Jeff 的解决方案非常相似(特别是,它对 CSV 做出了相同的假设),但第一行使用 input
,第二行使用 inputs
其余行,来自 jq Cookbook 的 "objectify" 的简化版本,以及 add
而不是主过滤器中的 reduce
:
jq -R -n '
def objectify(headers): . as $in
| reduce range(0; headers|length) as $i
({}; .[headers[$i]] = $in[$i] );
((input|split(","))[1:]) as $headers
| [ (inputs|split(",")) as $line
| { ($line[0]): ($line[1:] | objectify($headers)) } ]
| add
'