繁体   English   中英

使用 jq 将多个 JSON 的一个属性连接到一个文件中

[英]Concatenating one attribute of JSON from multiple into one file using jq

我有多个格式相似的 JSON 文件,这里有两个示例:

message_1.json

{
  "participants": [
    {
      "name": "Person One"
    },
    {
      "name": "Person Two"
    }
  ],

  "messages": [
    {
      "sender_name": "Person One",
      "timestamp_ms": 0002,
      "content": "Text2.",
      "type": "Generic"
    },
    {
      "sender_name": "Person Two",
      "timestamp_ms": 0001,
      "content": "Text1.",
      "type": "Generic"
    }
  ],
  "title": "Person One",
  "is_still_participant": true,
  "thread_type": "Regular",
  "thread_path": "inbox/SomeString"
}

message_2.json

{
  "participants": [
    {
      "name": "Person One"
    },
    {
      "name": "Person Two"
    }
  ],

  "messages": [
    {
      "sender_name": "Person Two",
      "timestamp_ms": 0004,
      "content": "Text4.",
      "type": "Generic"
    },
    {
      "sender_name": "Person One",
      "timestamp_ms": 0003,
      "content": "Text3.",
      "type": "Generic"
    }
  ],
  "title": "Person One",
  "is_still_participant": true,
  "thread_type": "Regular",
  "thread_path": "inbox/SomeString"
}

有没有一种方法可以使用jq来合并 JSON 文件,以便连接messages属性(顺序无关紧要)而其他属性不受影响?

合并 message_1.json 和 message_2.json 的结果如下所示:

消息.json

{
  "participants": [
    {
      "name": "Person One"
    },
    {
      "name": "Person Two"
    }
  ],

  "messages": [
    {
      "sender_name": "Person One",
      "timestamp_ms": 0002,
      "content": "Text2.",
      "type": "Generic"
    },
    {
      "sender_name": "Person Two",
      "timestamp_ms": 0001,
      "content": "Text1.",
      "type": "Generic"
    },
    {
      "sender_name": "Person Two",
      "timestamp_ms": 0004,
      "content": "Text4.",
      "type": "Generic"
    },
    {
      "sender_name": "Person One",
      "timestamp_ms": 0003,
      "content": "Text3.",
      "type": "Generic"
    }
  ],
  "title": "Person One",
  "is_still_participant": true,
  "thread_type": "Regular",
  "thread_path": "inbox/SomeString"
}

我有 11 个 JSON 文件,message_1.json,...,message_11.json。 我想将它们全部合并到这种形式的一个messages.json文件中,其中包含 JSON 文件中的所有消息 我如何通过 bash 使用jq来做到这一点?

这是一种方法,它的优点是不需要 -s 选项,这会消耗比必要更多的内存:

jq 'reduce inputs as $in (.;
  .messages += $in.messages)
' $(for i in $(seq 1 11); do echo message_$i.json ; done)

请注意,在这种情况下,应该在没有-n 选项的情况下调用 jq。

这是将spyql与 jq 一起使用的一种方法:

$ jq -c . message_*.json | spyql -Oindent=2 "SELECT first_agg(json->participants) AS participants, list_agg(json->messages) AS messages FROM json EXPLODE json->messages TO json"

jq 将 jsons 转换为 json 行格式(每行 1 个 json),然后 spyql 输出单个 json,其中第一次出现参与者并将所有出现的消息连接到一个数组中。

免责声明:我是 spyql 的作者。

一种方法,使用 slurp 模式,它将所有 JSON 文件内容放入一个数组中,然后通过将所有其他对象的消息附加到该数组中的第一个来处理它:

$  jq -s 'reduce .[1:][] as $m (.[0]; .messages += $m.messages)' message_*.json
{
  "participants": [
    {
      "name": "Person One"
    },
    {
      "name": "Person Two"
    }
  ],
  "messages": [
    {
      "sender_name": "Person One",
      "timestamp_ms": 2,
      "content": "Text2.",
      "type": "Generic"
    },
    {
      "sender_name": "Person Two",
      "timestamp_ms": 1,
      "content": "Text1.",
      "type": "Generic"
    },
    {
      "sender_name": "Person Two",
      "timestamp_ms": 4,
      "content": "Text4.",
      "type": "Generic"
    },
    {
      "sender_name": "Person One",
      "timestamp_ms": 3,
      "content": "Text3.",
      "type": "Generic"
    }
  ],
  "title": "Person One",
  "is_still_participant": true,
  "thread_type": "Regular",
  "thread_path": "inbox/SomeString"
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM