使用 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"]
}

三点很关键:

  1. 保留任何非 flag 或以 test

    开头的字段不变
  2. flag(space分隔值)转换为数组

  3. 任何以 test 开头的字段都将添加到一个数组 (tests),其中值是字段名称的剩余部分

可以使用/=拆分更新,startswith匹配字符串开头,to_entrieswith_entries操作涉及key的条目姓名:

jq '
  .flag /= " "
  | .tests = (to_entries | map(.key | select(startswith("test "))[5:]))
  | with_entries(select(.key | startswith("test ") | not))
'

Demo


另一个可能更有效的实现,它使用 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
  )
'

Demo


给定样本数据,两者都产生:

{
  "one": "1",
  "two": "2",
  "flag": [
    "f1",
    "f2",
    "f3"
  ],
  "tests": [
    "one",
    "two",
    "three"
  ]
}