使用 jq 将特定字段转换为数组
Transform specific fields into array(s) using jq
给出以下 JSON:
{
"one": "1",
"two": "2",
"flag": "f1 f2 f3",
"test one": "",
"test two": "",
"test three": ""
}
使用jq是否可以得到如下结果?
{
"one": "1",
"two": "2",
"flags": ["f1", "f2", "f3"],
"tests": ["one", "two", "three"]
}
三点很关键:
保留任何非 flag
或以 test
开头的字段不变
将flag
(space分隔值)转换为数组
任何以 test
开头的字段都将添加到一个数组 (tests
),其中值是字段名称的剩余部分
可以使用/=
拆分更新,startswith
匹配字符串开头,to_entries
和with_entries
操作涉及key的条目姓名:
jq '
.flag /= " "
| .tests = (to_entries | map(.key | select(startswith("test "))[5:]))
| with_entries(select(.key | startswith("test ") | not))
'
另一个可能更有效的实现,它使用 reduce
只在对象中循环一次:
jq '
reduce to_entries[] as {$key, $value} (null;
if $key == "flag" then .flag = $value / " "
elif $key | startswith("test ") then .tests += [$key[5:]]
else .[$key] = $value end
)
'
给定样本数据,两者都产生:
{
"one": "1",
"two": "2",
"flag": [
"f1",
"f2",
"f3"
],
"tests": [
"one",
"two",
"three"
]
}
给出以下 JSON:
{
"one": "1",
"two": "2",
"flag": "f1 f2 f3",
"test one": "",
"test two": "",
"test three": ""
}
使用jq是否可以得到如下结果?
{
"one": "1",
"two": "2",
"flags": ["f1", "f2", "f3"],
"tests": ["one", "two", "three"]
}
三点很关键:
保留任何非
开头的字段不变flag
或以test
将
flag
(space分隔值)转换为数组任何以
test
开头的字段都将添加到一个数组 (tests
),其中值是字段名称的剩余部分
可以使用/=
拆分更新,startswith
匹配字符串开头,to_entries
和with_entries
操作涉及key的条目姓名:
jq '
.flag /= " "
| .tests = (to_entries | map(.key | select(startswith("test "))[5:]))
| with_entries(select(.key | startswith("test ") | not))
'
另一个可能更有效的实现,它使用 reduce
只在对象中循环一次:
jq '
reduce to_entries[] as {$key, $value} (null;
if $key == "flag" then .flag = $value / " "
elif $key | startswith("test ") then .tests += [$key[5:]]
else .[$key] = $value end
)
'
给定样本数据,两者都产生:
{
"one": "1",
"two": "2",
"flag": [
"f1",
"f2",
"f3"
],
"tests": [
"one",
"two",
"three"
]
}