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

时间:2020-01-29 21:17:25

标签: json bash merge 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的结果如下所示:

messages.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来做到这一点?

2 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:-2)

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