jq操纵json文件

时间:2017-03-14 12:11:30

标签: json jq

在json下面输入输入:

{
    "name_A": {
        "logfile_one": [{
            "issue_desc": "desiredvalueone"
        }, {
            "issuetime": "desiredvaluetwo"
        }],
        "output": ["46312"]
    },
    "name_B": {
        "logfile_two": [{
            "issue_desc": "desiredvaluethirtyfour"
        }, {
            "issuetime": "desiredvaluetwo"
        }],
        "output": ["1", "2"]
    }
}

我们希望得到以下结果:

{
    "desiredvalueone": [{
        "name_A": "logfile_one"
    }],
    "desiredvaluetwo": [{
        "name_A": "logfile_one",
        "name_B": "logfile_two"
    }],
    ...
}

例如,使用t o_entries[] | .key,我们设法获得“name_A” “name_B”,但与我们试图达到的目标相差甚远。或者

[to_entries[] | {"key": .key, "value": .value[]}] | from_entries

输出

{
  "name_A": [
    "46312"
  ],
  "name_B": [
    "1",
    "2"
  ]
}

2 个答案:

答案 0 :(得分:0)

给定预期输出中的....引入了除问题陈述本身之外的若干不确定性,但以下程序确实产生的结果与所示的预期输出一致。

这里给出的解决方案的关键是用于组合JSON对象流的辅助函数:

# Combine a stream of JSON objects into a single object
# by converting the value v to [v] at each
# key, and then appending the arrays at each key.
def combine(s):
  reduce s as $o ({};
    reduce ($o|keys[]) as $k (.; .[$k] += [$o[$k]]  ) );

我理解的问题现在可以使用to_entries/0三次来解决;如果您不熟悉该过滤器,以下内容可能看起来相当难以理解:

combine( to_entries[]
   | .key as $k
   | .value
   | to_entries[]
   | select( .key | startswith("logfile_"))
   | .key as $innerkey
   | .value[]
   | to_entries[]
   | { (.value): { ($k): $innerkey }}
 ) | map_values(add)

给定输入的输出是:

{
  "desiredvalueone": {
    "name_A": "logfile_one"
  },
  "desiredvaluetwo": {
    "name_A": "logfile_one",
    "name_B": "logfile_two"
  },
  "desiredvaluethirtyfour": {
    "name_B": "logfile_two"
  }
}

答案 1 :(得分:0)

这是一个只假设输入具有以下结构的解决方案

{ 
  "k": {
     "k2": [{
        "k3": "v"

它的工作原理是生成格式为

的临时对象数组
{"v":"desiredvalueone","k":"name_A","k2":"logfile_one"}

然后按.v分组并组合组和包装值 在请求的数组中。

[
  . as $d
| [
      keys[] as $k                           # e.g "name_A"...
    | ($d[$k] | keys[]
       | select($d[$k][.][0]|type=="object")
       ) as $k2                              # k2:  "logfile_one"
    | $d[$k][$k2][] as $v                    # v:  {"issue_desc":"desiredvalueone"},
    | ($v|keys[]) as $k3                     # k3: "issue_desc"
    | {v:$v[$k3], k:$k, k2:$k2}              # {"v":"desiredvalueone","k":"name_A","k2":"logfile_one"}
  ]
| group_by(.v)[]
| reduce .[] as $t (
    {}
  ; .[$t.v] += {($t.k): $t.k2}
  )
]
| add
| map_values([.])

最终输出是

{
  "desiredvalueone": [
    {
      "name_A": "logfile_one"
    }
  ],
  "desiredvaluethirtyfour": [
    {
      "name_B": "logfile_two"
    }
  ],
  "desiredvaluetwo": [
    {
      "name_A": "logfile_one",
      "name_B": "logfile_two"
    }
  ]
}