使用jq合并两个包含公共数组的Apache Avro模式

时间:2019-06-27 04:59:11

标签: shell jq

我有两个Apache Avro模式(本质上是JSON)-一个是许多模式中的“通用”部分,另一个是。寻找一种将它们合并到Shell脚本中的方法。

base.avsc

{
  "type": "record",
  "fields": [
    {
      "name": "id",
      "type": "string"
    }
  ]
}

schema1.avsc

{
  "name": "schema1",
  "namespace": "test",
  "doc": "Test schema",
  "fields": [
    {
      "name": "property1",
      "type": [
        "null",
        "string"
      ],
      "default": null,
      "doc": "Schema 1 specific field"
    }
  ]
}

jq -s '.[0] * .[1]' base.avsc schema1.avsc对我来说不合并数组:

{
  "type": "record",
  "fields": [
    {
      "name": "property1",
      "type": [
        "null",
        "string"
      ],
      "default": null,
      "doc": "Schema 1 specific field"
    }
  ],
  "name": "schema1",
  "namespace": "test",
  "doc": "Test schema"
}

我不希望在“字段”数组中具有相同的键。并且"type": "record",可以移到schema1.avsc中,如果这样更容易。

预期结果应该是这样的(键的顺序没有区别)

{
  "name": "schema1",
  "namespace": "test",
  "doc": "Test schema",
  "type": "record",
  "fields": [
      {
        "name": "property1",
        "type": [
          "null",
          "string"
        ],
        "default": null,
        "doc": "Schema 1 specific field"
      },
    {
      "name": "id",
      "type": "string"
    }
  ]
}

无法弄清楚如何为我想要的内容在jq中编写表达式。

3 个答案:

答案 0 :(得分:2)

您需要加法(+)运算符来执行两个文件中记录的并集,并将两个文件中的公用记录fields合并为

jq -s '.[0] as $o1 | .[1] as $o2 | ($o1 + $o2) |.fields = ($o2.fields + $o1.fields) ' base.avsc schema1.avsc

此GitHub帖子pkoppstein's commentMerge arrays in two json files.采用的答案

jq manual在加法运算符+下说了

  

Objects是通过合并添加的,即将两个对象的所有键值对插入单个组合的对象中。如果两个对象都包含相同键的值,则+右侧的对象将获胜。 (对于递归合并,请使用*运算符。)

答案 1 :(得分:2)

这里有一个简洁的解决方案,可以避免“ s”:

public static void showToast(Context receiver, String message) {
    Toast.makeText(receiver, message, ...).show();
}

或者您可以简洁起见:

jq --argfile base base.avsc '
  $base + .
  | .fields += ($base|.fields)
' schema1.avsc

答案 2 :(得分:1)

作为替代解决方案,您可以考虑使用基于步行路径的UNIX实用程序 jtc 处理分层json。

这里的问题仅仅是递归合并,它与jtc看起来像这样:

bash $ <schema1.avsc jtc -mi base.avsc 
{
   "doc": "Test schema",
   "fields": [
      {
         "default": null,
         "doc": "Schema 1 specific field",
         "name": "property1",
         "type": [
            "null",
            "string"
         ]
      },
      {
         "name": "id",
         "type": "string"
      }
   ],
   "name": "schema1",
   "namespace": "test",
   "type": "record"
}
bash $ 

PS>披露:我是jtc-用于JSON操作的shell cli工具的创建者